前面幾篇文章我們討論了Oracle和PHP5結合Apache Web Server開發環境的搭建及最近發佈的PHP5語言的一些新特徵。在本文中,我們將討論如何讓PHP連結到Oracle Database。
PHP 連結到Oracle主要有以下幾種方式:
- Oracle擴展庫(Oracle Extension):為Oracle 早期版本(7.0 以前版本)所設計,現在已經廢棄不用了。
- OCI8擴展庫:如其名稱一樣,是為Oracle8i以後的版本所設計,支持9i,10g,11g等版本。
- PEAR DB Library:非常成熟的DB Layer Library。
- ADODB Library:第三方Library,經過廣大PHPer的測試和眾多PHP Web Application的驗證,穩定強壯的ADODB現在已經發佈了4.5.2版本。它是一個使用十分廣泛的第三方 Library。本文將重點介紹此 Library。
PHP連結Oracle,首先要打開PHP設定檔中的對Oracle擴展的支持,重啟Apache Server之後,寫一個簡單的 PHP 程式,phpinfo()
檢測Oracle Extension OCI8有沒有啟用。
Run 這個程式,在面頁上搜尋 oci8,如找得到說明 oracle extension啟用成功。 從http://adodb.sourceforge.net下載ADODB library,放到你的程式可以訪問到的Directory。 使用Oracle Extension連結Oracle 打開Oracle Extension之後,我們就可以用PHP built-in的OCI functions。
// 用Oracle預設的測試User scott/tiger連結到oracle database
$tnsname = 'hcp';
$conn = OCILogon('scott','tigger',$tnsname);
$stmt = OCIParse($conn,'select * from emp where empno>:emp_no');
OCIBindByName($stmt,':emp_no',1200);
$r = OCIExecute($stmt);
While (OCIFetchInto($stmt,$result))
{
Print_r($result);
Echo '
';
}// end while loop
// Line 1:指定這次連結的Oracle Database的tnsname叫做'hcp'。
// Line 2:用user 'scott',password 'tigger' 連結到'hcp',產生一個Connection Handler。
// Line 3:利用Connection Handler解析Select SQL Statement,其中傳了一個員工編碼 (emp_no)的變數。
// Line 4:給變數emp_no賦值。
// Line 5:執行查詢並把查詢的結果放到變數$r中。
// 用 ADODB 連結 Oracle
include_once '/path/to/adodb.inc.php';
$tnsname = 'hcp';
$Db = NewADODBConnection('oci8');
$Db->Connect($tnsname,'scott','tigger');
$result = $Db->Exeute('select * from emp where empno > :emp_nmo',
array('emp_no'=>1200));
while($row = $result->FetchRow()){
print_r($row);
echo '
';
}// end loop
忽略connection初始化部分代碼,兩段代碼十分相似。
ADODB 查詢 (Query)
如果您是從 Microsoft平臺轉換過來的程式撰寫人員,對Microsoft的Ado不會陌生。你也可以用標準的MS的方式,如 MoveNext()方法。
$result = $Db->Execute('select * from emp
where empno>:emp_no',array('emp_no'=>1200));
While(!$result->EOF){
Print_r($result->fields);
$result->MoveNext();
}// end loop
如果您想傳回2-D array的話,您可以使用 GetArray(),GetRow()或是GetAll()。
$recordset = $Db->GetArray('select * from emp');
Print_r($recordset);
$recordset1 = $Db->GetAll('select * from emp');
Print_r($recordset1);
$row = $Db->GetRow('select * from emp where empno=1200'); // only one row selected
Print_r($row);
如果只需要挑一個column,比如我們要得到資料count的筆數:
$cnt = $Db->GetOne('select count(*) from emp');
Echo $cnt;
分頁模式查詢 (Pagination Query)
Web Application在查詢到大量資料時,常常會用到分頁的功能。像MySQL等Database本身就提供了limit的功能。可是在Oracle中卻沒有此built-in功能供我們來使用。如果不用ADODB Library的話,自己也可以寫Nesting SQL來實現這個功能,不過非常麻煩,也容易出錯。值得慶幸的是,ADODB已經為我們準備好了同MySQL limit一樣功能的function供調用。您不用瞭解其內部複雜的運作原理,調用它就像 built-in的function一樣簡單。
// mysql sql
$sql = 'select empno,ename from emp where deptno = 100 limit 3,5';
$rs = $Db->GetArray($sql);
// Oracle SQL
$sql = 'select *
from (select rownum as xrownum, empno, ename from emp)
where xrownum > 3
and xrownum <= 5';
$rs = $Db->GetArray($sql);
// Using ADODB
$offset = 3;
$limitrows = 2;
$rs = $Db->SelectLimit('select rownum as xrownum,empno,ename from emp',$limitrows,$offset);
查詢模式設定(Fetch Mode)
ADODB Library定義了三個常量 (constant),分別代表三種Fetch Mode。 ADODB_FETCH_NUM:傳回以數字為下標(index)的array,設定方法: $Db->SetFetchMode(ADODB_FETCH_NUM); ADODB_FETCH_ASSOC:傳回以欄位名稱為下標(index) 的array,設定方法: $Db->SetFetchMode(ADODB_FETCH_ASSOC); ◎注意:Oracle中是傳回大寫欄位名稱為下標(index)的 array。 ADODB_FETCH_BOTH: 同時傳回數位和文字為下標(index)的 array,設定方法: $Db->SetFetchMode(ADODB_FETCH_BOTH); ◎注意:除非有特殊的需要,不建議在大量資料時使用此Mode,會最影響 Performance。ADODB中 Oracle default fetch Mode就是ADODB_FETCH_BOTH,建議手動設定成欄位元名稱或數字為 index的Mode。