產品特寫
     
字體 放大 標準 縮小

  • Oracle擴展庫(Oracle Extension):為Oracle 早期版本(7.0 以前版本)所設計,現在已經廢棄不用了。
  • OCI8擴展庫(oracle Extension):如其名稱一樣,是為Oracle8i以後的版本所設計,支持9i,10g,11g等版本。
  • PEAR DB Library:非常成熟的DB Layer Library,詳細請參考PH官方網站 http://pear.php.net 本文不做詳細介紹。
  • ADODB Library:第三方Library,經過廣大PHPer的測試和眾多PHP Web Application的驗證,穩定強壯的ADODB現在已經發佈了4.5.2版本。它是一個使用十分廣泛的第三方 Library。本文將重點介紹此 Library。

    PHP ADODB官方網站: http://adodb.sourceforge.net


開始
PHP連結Oracle,首先要打開PHP設定檔中的對Oracle擴展的支持,如何打開Oracle Extension 請參考前面的 《Oracle & PHP5 Web 應用程式開發(入門篇) -- 運行環境搭建》 的“運行環境的搭建”。
重啟Apache Server之後,寫一個簡單的 PHP 程式,檢測Oracle Extension OCI8有沒有啟用。
如:

File: phpinfo.php
<?php
  phpinfo();
?>


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。
<?php
 $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 ‘<br/>’;
 }// 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
<?php
  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 ‘<br/>’;
  }// end loop
?>

以下將比較OCI8和ADODB 的代碼。這裏忽略connection初始化部分代碼,兩段代碼十分相似。

OCI8 ADODB ADODB
$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 ‘<br/>’;
}// end loop

$result = $Db->Exeute(‘select *
          from emp
 where empno > :emp_nmo’,
  array(‘emp_no’=>1200));
 while($row= $result->FetchRow()){
 print_r($row);
 echo ‘<br/>’;
}// end loop

ADODB 查詢 (Query)
如果您是從 Microsoft平臺轉換過來的程式撰寫人員,對Microsoft的Ado不會陌生。你也可以用標準的MS的方式,如 MoveNext()方法。以上面的代碼為例:
<?php
   $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()方法。
如下面的代碼:
<?php
  $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的筆數:

<?php
  $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如下:
<?php
  $sql = ‘select empno,ename from emp where deptno = 100 limit 3,5’;
  $rs = $Db->GetArray($sql);
?>


Oracle中直接用 SQL 的實現:
<?php
$sql = ‘select *
     from (select rownum as xrownum, empno, ename from emp)
     where xrownum > 3
     and xrownum <= 5’;
  $rs = $Db->GetArray($sql);
?>


Using ADODB的實現:
<?php
  $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。


限於篇幅,本期就介紹到此。敬請期待下一期電子報中的《Using ADODB with PHP and Oracle (Part II) 》。



>>返回電子報首頁

資通電子報之所有文字及圖片為資通電腦公司所有。 未經確認授權,嚴禁轉貼節錄。
還有更多資訊在本公司的網站上,歡迎參觀 網址:http://www.ares.com.tw/
對我們有任何問題、建議 請來信通知我們e-mail:ouying@ares.com.tw