模仿前人的程式,寫了一段超迷你的程式要連 Oracle,但一直跳出的錯誤訊息:
PHP Fatal error: Call to undefined function Ora_Logon()
查了一下官方文件,Ora_* 這種函式看起來不是官方支援的,網路上的文章倒是不少,可能是過時所以被拿掉了吧?向同事拿了他開發機上頭 PHP 的 ext 資料夾底下的 php_oracle.dll,嘗試在 php.ini 加上 "extension=php_oracle.dll",結果出現新的錯誤:
PHP Startup: Unable to load dynamic library 'C:/php/ext/php_oracle.dll' - 找不到指定的模組。
怪了,明明就放在一樣的路徑下。研究別人找不到模組的原因,有人說和引用順序有關,於是放在 ";extension=php_oci8.dll" 這行之後,一樣沒用,不過把 ";extension=php_oci8.dll" 的註解拿掉(這行最前面的分號刪除掉),「找不到指定的模組」這個錯誤訊息就消失了。但還是不認得 Ora_Logon() 這個函式。
《[筆記]oracle+php+apache在windows下的的安裝方式》這篇提醒了我,php_oci8.dll 需要安裝 Oracle Client library 才能使用(其實 PHP 官方文件也有說啦 XD),因此我按照網路上的建議下載了 Oracle Instant Client,PHP 官方文件說要記得在 PATH 裡設定 Oracle Instant Client 的路徑。
一開始我因為 Windows 是 64 位元版本,下載了 64 bits 版本的 Oracle Instant Client (instantclient-basic-win-x86-64-10.2.0.3.0.zip),一直跳出錯誤訊息:
PHP Warning: PHP Startup: Unable to load dynamic library 'C:/php/ext/php_oci8.dll' - %1 不是正確的 Win32 應用程式 。
後來看了 Oracle 官網上的教學文章:《 在 Linux 和 Windows 上安裝 PHP 和 Oracle Instant Client》,裡說到一句話:「因為 PHP 是 32 位,所以使用 32 位版本的 Instant Client。」
所以把 Oracle Instant Client 換成 32 bits 版本 (instantclient-basic-win32-10.2.0.3-20061115.zip) 就沒事了。
這時候 oci8 模組已經啟用了,可是舊版的 oracle 模組還是載不進來,又再次看見這個錯誤訊息:
PHP Warning: PHP Startup: Unable to load dynamic library 'C:/php/ext/php_oracle.dll' - 找不到指定的模組。
對此現象深感無奈,加上 ora_* 的函式都已經過時了,於是這篇文章的標題就從「使用 Oracle 相關函式 (ora_*) 的前置設定」變成「如何使用 PHP 的 OCI8 連線至 Oracle」了。XD
OCI8 模組可以用了以後,我連線一直失敗。我設定的 connection string 是這樣(IP 和 SID 是假的,請依實際狀況填寫):
$oracle_db = "
(DESCRIPTION=
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 10.1.1.1)
(PORT = 1521)
)
)
(CONNECT_DATA=
(SID = testdb)
)
)";
得到的錯誤訊息是這個:
ORA-12154: TNS:could not resolve the connect identifier specified
但萬分悲情的是,我試著把 connection string 改成這樣:
$oracle_db = "//10.1.1.1/testdb"
赫然發現真正的錯誤訊息是我的帳號密碼根本 key 錯:
ORA-01017: invalid username/password; logon denied
打錯密碼就打錯密碼,有必要跟我說我的連線無法識別嗎?(淚)
所以最後記錄一下我連線取資料所使用的程式碼片段:
<?php
$oracle_db="
(DESCRIPTION=
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 10.1.1.1)
(PORT = 1521)
)
)
(CONNECT_DATA=
(SID = testdb)
)
)";
$sql="select city_name, city_id from city";
$conn=oci_connect($db_user_id,$db_user_pwd,$oracle_db);
if(!$conn){
echo"db access error: ".oci_error();
}
else{
try{
$stid=oci_parse($conn,$sql);
oci_define_by_name($stid,'CITY_ID',$city_id);
oci_define_by_name($stid,'CITY_NAME',$city_name);
oci_execute($stid);
while(($row=oci_fetch_array($stid,OCI_ASSOC+OCI_RETURN_NULLS))){
echo"city_id: ".$bond_id.", city_name: ".$city_name;
}
}
catch(Exception $e){
echo$e->getMessage();
}
if($stid){oci_free_statement($stid);}
if($conn){oci_close($conn);}
}
?>
留言列表