PEAR DB將數據庫工作簡化

有經驗的PHPer應該對PEAR*都不會陌生,不過對新手來說,簡單的練習PEAR應該不必派上用場,不過在開始接觸複雜的編程時,PEAR對PHPer來說可以說是一個很有效的工具。到底什麼是PEAR我這裏不詳細討論了,因爲答案都在pear.php.net,不過這裏得介紹一個很好用的工具 -- DB,這是一個以PEAR爲基礎的數據庫抽象層;雖然PHP已經有內建的數據庫函式,不過功能有限,而且不容易轉移平臺。例如通常連接MySQL的函式是mysql_connect(),而PostgreSQL則是pg_connect(),雖然你大可將mysql_[x]改成pg_[x],不過如果你的數據庫抽象層的源碼超過500行的話這將是一個惡夢!如果你的數據庫函式是散佈在你的源碼,那就更恐怖了。所以,這時候需要有一個跨平臺的數據庫界面抽象層來爲你完成大部分的工作,包括連接,query,update等等,而且還需要提供debug的功能。PEAR DB正是一個這樣的工具,提供多種平臺包括dbase, Frontbase, InterBase, Informix, MiniSQL, MSSQL, MySQL, Oracle, ODBC, PostgreSQL, SQLite, Sybase。PEAR DB可以完全作爲一個PHP程序的數據庫層,而且速度也很理想(當然不比直接用mysql_query來得快,不過在大型的程序中可以凸現它的效果),所有的功能都包含在三個類型中,用法也很簡單。以下我將介紹這三種類型:

1.DB類
DB類爲PEAR DB的主幹,所有的函式以靜態呼叫,所以在運用的時候不需要實體化,可以直接呼叫。當你有了其中一個以上所提到的數據庫之後,第一步就是連接數據庫了,利用DB::connect()再加上一個[url=http://pear.php.net/manual/en/package.database.db.intro-dsn.php]DSN[/url](一段連接數據庫所需的字串。DSN的格式如下:

[code]
sqltype://username:passwd@protocol+host/database?option=value
Example: $dsn =  “mysql://username:passw0rD@localhost/mydb”
[/code]

Sqltype是指數據庫平臺,詳細的字串可以到DSN網頁參考。
接下來再把DSN傳入DB::connect()參數
[code]
$conn = & DB::connect($dsn);

If(Pear::isError($conn)){
        die($conn->getMessage());
}
[/code]
$conn是由DB::connect()傳回來的一個界面實體,接下來它將扮演一個很重要的角色;注意下面一段,這裏運用到PEAR::isError()來檢查$conn是否是DB error物件,要是有錯誤的話,$conn將會自動釋出錯誤信息。getMessage()這個函式存在於DB error類型,隨時可以調用。



*PEAR一般上是隨PHP一起安裝的,如果要另外安裝的話,可以下在PHP的完整壓縮包,執行裏面的do-pear.bat就可以了。(DB已經包含在PEAR安裝包裏面了,所以不需要另外下載。)


 

 
2.DB::common界面

剛剛的$conn就是這個界面類型的實體,這個界面將負責大部分的數據工作,包括select, update, insert等等。這個界面包含了大量功能強大的函式,不過我將介紹幾個重要的。

[code]
--Select

$sql = “SELECT * FROM blah”;
$conn->setFetchMode(DB_FETCHMODE_ASSOC);

$result = $conn->query($sql);

$row = $result->fetchRow();
print_r($row);

$conn->disconnect();
[/code]

如果你熟悉PHP的數據庫方法的話,應該對[x]_fetch_assoc不會陌生,沒錯,意思大致上相同。DB::common 的默認設定是DB_FETCHMODE_ORDERED, 和[x]_fetch_row大致上相同,以上例子我將fetchmode利用DB::common::setFetchMode()將它改爲DB_FETCHMODE_ASSOC,得出的$result將會和[x]_fetch_assoc相同,都是以fieldname作爲引索。這裏的$result( DB::result ) 和mysq_query()所傳回的差不多,是PEAR DB裏面另外一個重要的類型,稍候會作介紹;如果需要得到一行的數據,可以用DB::result::fetchRow(),就可傳回一個數據行的陣列。

之前所提到的PEAR::isError()也可以用來檢查$result的結果是否有錯誤。編碼如下:
[code]
if(PEAR::isError($result)){
        die($result->getMessage());
}
[/code]
和之前一樣如法炮製,只是將對象由DB::common改成DB::result。
DB::common也提供了兩個很方便的方法讓PHP能夠簡單地處理INSERT和UPDATE,prepare()和execute(),這兩個組合可以讓你很輕鬆的同時處理多個INSERT和UPDATE  statement。prepare()主要現載入需要執行的statement,而execute將負責執行,同時也載入所需的參數。看看以下的例子:
[code]

$conn->prepare(“INSERT INTO foo (fname, fage, flocation) VALUES (? , ? , ? )”);
$data = array(“foo”,23,”earth”);
$conn->execute($stn, $data);

if(PEAR::isError($stn)){
        die($stn->getMessage());
}

$conn->freePrepared();
[/code]

“?”這裏是代表參數,$data裏面的數據會依次序被傳入prepare()裏面的statement裏面的”?”參數。所有的數據將會自動呼叫escaped string來將一些意義符號字串化,而且execute()也會自動辨認數據類型,例如數字,字串等等。那麼如果要輸入超過一行以上的數據呢?可以簡化嗎?答案是肯定可以了,參考下面的例子你就會發現,DB是多麼不可思議了
[code]

$conn->prepare(“INSERT INTO foo (fname, fage, flocation) VALUES (? , ? , ? )”);
$data = array(array(“foo”,23,”earth”),
array(“faa”,21,”moon”),
array(“fee”,25,”mars”)
array(“fii”,19,”Pluto”));
$conn->executeMultiple($stn, $data);

if(PEAR::isError($stn)){
        die($stn->getMessage());
}

$conn->freePrepared();
[/code]
幾個繁雜的程序在幾行就可以完成了,關鍵就在於$data和DB::common::executeMultiple()。$stn是execute()或executeMultiple()所傳回的結果,他有三種可能性:第一,DB::result,可以將statement的結果數據轉爲result實體;第二,定義常數DB_OK,代表statement成功執行;第三,DB error實體,後面的PEAR::isError()就是檢查傳回是否爲DB error。如果要用同一個DB::common資源進行另一個query,必須呼叫DB::common::freePrepared()來清除之前prepared()內的statement。

DB::common可以說是PEAE DB的最重要的工作界面,大部分和數據的接觸都在這裏進行,而且功能也強大。除了以上說明的幾個方法之外,DB::common還有很多個方法也是很實用的。詳細的說明可以到pear.php.net查看。

待續..


 

 
3.DB result

顧名思義,DB result是由DB::common在query之後傳回的數據組合。DB result本身是一個物件,所以內付幾個很方便的方法。

--fetchInto()和fetchRow()
以上兩個方法用法大致上相同,唯一個差別就在於前者將結果傳給參數( $result->fetchInto($row));後者本身傳回結果($row = $result->fetchRow()) 。與PHP內建的方法一樣,fetchrow()每次將一行資料傳回。

--numCols()和numRows()
這兩個方法將分別傳回DB result內Columns和Rows的數量。

--free()
將DB result內的資料從記憶體中撤走。

這個例子是將以上幾種方法一起運用:
[code]
$conn->setFetchMode(DB_FETCHMODE_ASSOC);
$result = $conn->query($sql);

echo “There are “.$result->numRows().” Results found and “.$result->numCols().” fields are available.”;

while( $row = $result->fetchRow()){
        echo $row[‘name’];
}

$result->free();
[/code]

後記:
以上資料是基礎篇,如果想要再深入可以到http://pear.php.net/package/DB PHP PEAR的網頁,裏面有詳細的文件供參考。除了DB之外,PEAR網頁內也有各式各樣的數據庫抽象層讓人免費下載,包括LDAP, ADODB,還有類似DB的MDB2也是一個不錯的選擇。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章