| 前言 為什麼要使用資料庫類庫?
 初學者 (甚至一些非初學者)常常犯的錯誤,就是在開發應用程式的時候,缺乏對未來的考慮。假如有一天,你的程式需要使用其它的資料庫,難道你還需要重新寫一篇針對於這個版本資料庫的程式嗎?這不是不可能發生的,尤其是當目前的資料庫可能不適合你當前的需要的時候。 但是當你做這一切的時候 ,你會發現絕非你想像的那樣容易:每一個 DBMS 有不同的函數。舉例來說:在 Mysql 中連接資料庫的函數為 mysql_connect(),而在MSSQL卻是 mssql_connect()。重新查看你所有的代碼,然後修改所有操作資料庫的函數和查詢語法,這絕不是一項簡單的工作。程式會經常的被捆綁到了錯誤的資料庫上,以至無法在運行時達到最優性能。資料庫類庫就是這樣產生的。它允許你通過同樣的代碼來操作不同的資料庫。一個設計良好的資料庫類庫可以完美的改變這一切。它允許你通過極小的修改,就能轉接到其他資料庫:無論你要連接什麼資料庫管理系統,只要使用同一個的函數,和不同的參數。舉例來說, 在 ADOdb 中,只需簡單地將 $db = NewADOConnection('access ') 修改為$db = NewADOConnection('mysql'),這樣,你就輕鬆的把你的程式從 Access 資料庫轉移到了 Mysql 資料庫中。現在網路上已經有了很多這樣的資料庫類庫,比如Pear,PHPlib,我也已經在工作中使用它們了,也許你也曾經用過。但本文僅將重點放在我所特別關注的 ADOdb。本文我只簡要地作一個介紹,使你能夠馬上運用它來開發你的下一個專案。以後的文章中我們將會循序漸進的對它進入更深入的瞭解。
 目前,ADOdb 支援的資料庫包括 MySQL, PostgreSQL,Interbase,Firebird,Informix,Oracle,MS SQL 7,Foxpro,Access,ADO,Sybase,FrontBase,DB2 和 generic ODBC。
 ADOdb 的安裝
 安裝 ADOdb 是一件極期容易的事,相信聰明的你一定不會感到吃力。
 首先, 確定你正在運行的 PHP 是 4.0.4 版或更新版。 如果不是,我強列建議你升級!
 從 PHP Everywhere 網站下載 .zip 或 .tgz 檔,解壓縮到你所選的路徑下。
 這個路徑不應在網頁目錄(WWWTREE,譯者注:如果你的網頁是在/www/下,那麼,這個目錄就不應為/www/here)下!雖然ADOdb的包含檔已經使用了 .inc.php 的副檔名 ,使得伺服器即使是在最糟糕的配置下,也不會將這些.inc檔通過明文方式在流覽器中顯示出來,但是我們向來不提倡將庫函數檔放在網頁目錄下的行為。然後把下載下來的檔運行:tar -zxvf adodb350.tgz 解壓,在Windows下你可以使用一個你喜歡的解壓軟體來操作,這樣,你會得到一個 adodb 的目錄其下包括了許多子目錄。
 測試你的安裝
 好了,讓我們來測試一下你的安裝吧。 通過在腳本中添加下列三行代碼來測試你的安裝是否成功。注意要把代碼中的參數修改成你自己的。
 include("$adodb_path/adodb.inc.php"); // includes the adodb library
 $db = NewADOConnection('$database_type'); // A new connection
 $db->Connect("$host", "$user", "$password", "$database_name");
 現在你已經擁有一個資料庫連線物件 $db 了。 你也可以使用 ADONewConnection 來替換 NewADOConnection —— 這兩個是同一函數的不同的名字。 連接的資料庫變數 $database_type 需要針對你的實際情況改成你所需要的。可以使用以下列表中的一個(括弧內的為描述部分,不要在代碼中使用):
 
 如果你的連結代碼出現了錯誤的提示,那麼你首先要檢查的地方就是在路徑或連接的變數上。在你責備 ADOdb 之前,請確定你是已經正確的使用那些變數。(很多朋友常花太多時間去修正這些顯而易見的錯誤。) 如果連接沒有任何錯誤提示,那麼我們現在已經可以在我們的項目中來使用 ADodb 了。access (Microsoft Access/Jet)ado (Generic ADO, the base for all the other ADO drivers)ado_access (Microsoft Access/Jet using ADO)ado_mssql (Microsoft SQL Server using ADO)db2 (DB2)vfp (Microsoft Visual FoxPro)fbsql (FrontBase)ibase (Interbase 6 or before)firebird (Firebird)informix72 (Informix databases before Informix 7.3)informix (Informix)maxsql (MySQL with transaction support)mssql (Microsoft SQL Server 7)mssqlpo (Portable mssql driver)mysql (MySQL without transaction support)mysqlt (MySQL with transaction support, identical to maxmysql)oci8 (Oracle 8/9)oci805 (Oracle 8.0.5)oci8po (Oracle 8/9 portable driver)odbc (Generic ODBC, the base for all the other ODBC drivers)odbc_mssql (MSSQL via ODBC)odbc_oracle (Oracle via ODBC)oracle (Oracle 7)postgres (PostgreSQL)postgres64 (PostgreSQL 6.4)postgres7 (PostgreSQL 7, currently identical to postgres )sqlanywhere (Sybase SQL Anywhere)sybase (Sybase)
 通過你的腳本連接到資料庫
 把上邊的代碼加入到你的代碼前,讓我們先退一步。我們最好能把上邊的代碼用我們自己的方法來封裝起來。這樣可以使你的程式變得更靈活、更具移植性。如果你直接把上面的代碼插入到你的專案的每個檔中,如果將來專案的路徑改變了,將會很容易產生錯誤,如果你的密碼改變了,你可能需要對你所有的腳本進行修改,這樣將會影響我們使用庫函數的初衷。並且,因為你的密碼資訊是在WEBTREE下的,這將產生隱患。我推薦將密碼資訊放在一個獨立的包含檔中,比如在 ADOdb 安裝目錄下的某個地方。如果你要在其他伺服器上運行你的程式時,你就不能保證目錄結構會是相同的,所以,你要確保這個路徑是正確的。我建議使用PHP 的自動包含功能來自動地包含這個檔。
 
 include("$adodb_path/db_values.inc.php");
 include("$adodb_path/adodb.inc.php");
 $db = NewADOConnection('$database_type');
 $db->Connect("$host", "$user", "$password", "employees");
 
 如果你也想要使用持久連接, 不是每次創造一個新的連接(這使許多WEB應用程式得到了加速,但是要注意有些資料庫是不支援的)。可以使用 PConnect 替換掉 Connect。
 文件 db_values.inc.php 是我們的資料庫資訊檔,內容為(你需要把下面代碼中的變數改成你自己的):
 <?php
 $database_type="mysql";
 $host = "localhost"; // 本地資料庫
 $user = "ian"
 $password = "let_me_in"
 ?>
 
 你可以在 php.ini 配置中設定自動包含我們的設定檔,具體操作可以修改 PHP.ini 的下述行:
 ; Automatically add files before or after any PHP document.
 auto_prepend_file = /usr/local/build/apache/www/tool_lib/defaults.inc
 auto_append_file =
 
 
 文件 defaults.inc 包含了 $adbdb_path 的值:
 <?
 $adodb_path = "/usr/local/build/apache/www/tool_lib/";
 ?>
 
 還有其他方式來實現它,但是我發現這種方法在移植時,可以相對地減少複雜度。
 
 從一個資料庫中進行選擇(SELECT)操作
 當同時使用開發良好的庫函數,和PHP自身提供的函數時,可以有多種方法來訪問資料庫。用什麼方法,完全取決於你自己的喜好。
 這裡是一個簡單的例子:
 $sql = "SELECT surname, age FROM employees";
 $rs = &$db->Execute($sql);
 if (!$rs) {
 print $db->ErrorMsg(); // Displays the error message if no results could be returned
 }
 else {
 while (!$rs->EOF) {
 print $rs->fields[0].' '.$rs->fields[1].'<BR>';
 // fields[0] is surname, fields[1] is age
 $rs->MoveNext();  //  Moves to the next row
 }
 }
 
 
 在上例中,$rs->fields 是一個包含返回值的陣列。陣列索引被賦予了初始的數位,你也可以按下面的方法來指定其索引:
 $sql = "SELECT surname, age FROM employees";
 $db->SetFetchMode(ADODB_FETCH_ASSOC); // Return associative array
 $rs = &$db->Execute($sql);
 if (!$rs) {
 print $db->ErrorMsg(); // Displays the error message if no results could be returned
 }
 else {
 while (!$rs->EOF) {
 print $rs->fields['surname']." ".$rs->fields['age']."<BR>";
 $rs->MoveNext();  //  Moves to the next row
 }  // end while
 } // end else
 
 
 對結果流覽的另一個可選的方法是將每條記錄作為一個物件返回。 ADOdb 有一個 FetchNextObject() 的函數來實現這一功能,指針會自動地移到下一條記錄。
 $sql = "SELECT surname, age FROM employees";
 $db->SetFetchMode(ADODB_FETCH_ASSOC); // Return associative array
 $rs = &$db->Execute($sql);
 if (!$rs) {
 print $db->ErrorMsg(); // Displays the error message if no results could be returned
 }
 // loop through results
 while ($row = $rs->FetchNextObject()) {
 // The field names need to be uppercase
 print $row->SURNAME." ".$row->AGE."<BR>";
 }
 
 
 插入、更新記錄
 基本的 INSERT 操作方便、快捷, 擁有與SELECT一樣的語法。
 $sql = "INSERT INTO employees (surname, age) values ('Clegg','43')";
 if (!($db->Execute($sql))) {
 print 'Error inserting: '.$db->ErrorMsg().'<BR>';
 }
 
 
 庫函數真正的優點,在於它允許你通過相同的語法將記錄放入不同的資料庫之內,這在以前是絕對不可能的。通常有兩種發生的情形。
 第一種,引號。所有的引號需要用脫字元(即`符號,鍵位在Tab鍵的上邊)代替,否則會引起語法錯誤。但是一些資料庫使用一個單引號,另外一些則使用兩個單引號。所以,你應當使用 ADOdb 中的 qstr() 而不是 PHP 中的 addslashes()。這樣,返回值就將與你所使用的資料庫相吻合了。
 第二種,日期。許多資料庫接受跟他們的日期類型不一致的、不相容的格式。 ADOdb 有一個 DBDate() 函數,可以將 Unix 的 timestamp, 或 ISO(Y-m-d) 格式轉換成任意格式,以此來滿足你的資料庫的需求。 見下例:
 $employee_surname = $db->qstr("d'Angelo");
 $arrival_time = $db->DBDate(time());
 // The above two functions also add the enclosing quotes, so, $arrival_time, not '$arrival_time'
 $sql = "INSERT INTO employee_arrival (arrival_time,surname) values ($arrival_time,$employee_surname)";
 if (!($db->Execute($sql))) {
 print 'Error inserting: '.$db->ErrorMsg().'<BR>';
 }
 
 你可以以完全相同的方式更新資料庫,舉例來說:
 $sql = "UPDATE employees SET age='44' WHERE id='121')";
 if (!($db->Execute($sql))) {
 print 'Error updating: '.$db->ErrorMsg().'<BR>';
 }
 
 以上僅僅是 Adodb 的一些基本操作 —— 下次我們將會關注一些 ADOdb 提供的比較深層次的東西。 如果我已經使你胃口大開,而且你已經不能再等待, 我建議你去PHP Everywhere看一下,這個網站是ADOdb的專業網站,裡面有很多有用的説明資訊。
 
 
 
  |