ADODB详解
17.4? ADODB
PHP在數(shù)據(jù)庫(kù)的支持上是很令人稱(chēng)道的,幾乎所有的知名數(shù)據(jù)庫(kù)系統(tǒng)都有對(duì)應(yīng)的函數(shù)庫(kù)支持,而且支持得很完整。但遺憾的是,每一群數(shù)據(jù)庫(kù)支持函數(shù)無(wú)論在名稱(chēng)或參數(shù)結(jié)構(gòu)上,都有很大的差異,這使得PHP的系統(tǒng)開(kāi)發(fā)者在面臨更換數(shù)據(jù)庫(kù)時(shí),總會(huì)覺(jué)得痛苦萬(wàn)分。
難道這個(gè)問(wèn)題就沒(méi)有解決方法嗎?當(dāng)然有,答案就是將要介紹的ADODB這個(gè)PHP類(lèi)庫(kù)。
ADODB提供了完整的方法和屬性,可以用來(lái)控制數(shù)據(jù)庫(kù)系統(tǒng),更棒的是你只要記得它的功能即可,因?yàn)椴煌臄?shù)據(jù)庫(kù)系統(tǒng),只要修改一個(gè)屬性值,ADODB就會(huì)自動(dòng)依據(jù)設(shè)定取用正確的PHP函數(shù)。
此外,再配合數(shù)據(jù)庫(kù)系統(tǒng)修改SQL命令,這樣PHP系統(tǒng)就可以在最短的時(shí)間內(nèi)更換到另一個(gè)數(shù)據(jù)庫(kù)系統(tǒng);如果在編寫(xiě)程序時(shí),對(duì)SQL命令能做妥善規(guī)劃,那就更快了。
經(jīng)過(guò)以上的介紹,相信你已經(jīng)對(duì)ADODB的功用有所了解了,以下為ADODB的詳細(xì)介紹。
下載ADODB:可以在http://adodb.sourceforge.net/ 取得最新版的ADODB(見(jiàn)圖17-2)。
圖17-2
ADODB的最新版本是adodb495a版,根據(jù)需要,可以下載完整版本的ADODB。如果您主要使用MySQL,則可以下載ADODB的lite版本,減少體積和一些不必要的系統(tǒng)開(kāi)銷(xiāo)。
17.4.1? 使用ADODB
由于PHP的數(shù)據(jù)庫(kù)存取函數(shù)沒(méi)有標(biāo)準(zhǔn)化,所以需要一組函數(shù)庫(kù)或類(lèi)別來(lái)隱藏不同數(shù)據(jù)庫(kù)函數(shù)界面間的差異。可以實(shí)現(xiàn)相對(duì)簡(jiǎn)單的數(shù)據(jù)庫(kù)系統(tǒng)移植,這就是ADODB抽象層要實(shí)現(xiàn)的目標(biāo)。
ADODB目前支持的數(shù)據(jù)庫(kù)系統(tǒng)MySQL、Oracle、MS SQL Server、Sybase/Sybase SQL Anywhere、Informix、PostgreSQL、FrontBase、Interbase(Firebird及Borland版本)、Foxpro、Access、ADO和ODBC連接。
與其他數(shù)據(jù)庫(kù)抽象層相比,其他類(lèi)大多集中在處理與SELECT操作有關(guān)的內(nèi)容,而ADODB對(duì)于INSERT及UPDATE操作也提供額外的支持,并且可以很快連接到多類(lèi)數(shù)據(jù)庫(kù),提供的統(tǒng)計(jì)方法,在底層實(shí)現(xiàn)字串連接及字串標(biāo)記變量的差異處理(在某些數(shù)據(jù)庫(kù)中,字串的連接和標(biāo)記符號(hào)是有差異的)。
字段類(lèi)型對(duì)照系統(tǒng)是ADODB抽象層的特性之一,所以我們可以描述像CHAR、TEXT(而Oracle是Clob類(lèi)型)及STRING這樣的通用字段類(lèi)型,而不必理會(huì)采用的數(shù)據(jù)庫(kù)使用的是哪種類(lèi)型,它會(huì)在底層替我們做對(duì)應(yīng)和轉(zhuǎn)換。
因此使用ADODB開(kāi)發(fā),對(duì)于系統(tǒng)來(lái)說(shuō)移植相對(duì)變得容易,因?yàn)樗信c數(shù)據(jù)庫(kù)相依存的程序代碼被都隱藏在后端,使用者不再需要去移植類(lèi)別里的邏輯。
ADODB擁躉者很多,很多著名的開(kāi)源軟件:PostNuke、phpWiki、Mambo、eGroupware等,都使用ADODB作為數(shù)據(jù)庫(kù)抽象類(lèi)庫(kù)。
17.4.2? ADODB安裝
首先要將全部文件解壓縮到Web服務(wù)器目錄里,如lib/adodb。要測(cè)試ADODB則需要一個(gè)數(shù)據(jù)庫(kù),打開(kāi)testdatabase.inc.php 這個(gè)文件,并且修改連接參數(shù),以適合你所使用的數(shù)據(jù)庫(kù)。這個(gè)程序會(huì)在你的數(shù)據(jù)庫(kù)中建立一個(gè)新的資料表,以支持我們提供的測(cè)試程序及范例。
17.4.3 ?啟動(dòng)ADODB
當(dāng)要執(zhí)行ADODB時(shí),至少有兩個(gè)文件要被加載進(jìn)來(lái),第一個(gè)是 ADOdb.inc.php,這里面包含了所有數(shù)據(jù)庫(kù)類(lèi)中要被使用的函數(shù)。而對(duì)數(shù)據(jù)庫(kù)操作的程序代碼則被放置在ADOdb.inc.php文件里。
ADODB可以連接的名稱(chēng)及對(duì)應(yīng)的數(shù)據(jù)庫(kù)系統(tǒng),如表17-1所示。
表17-1
| 連接標(biāo)識(shí) | access | mssql | mysql | oci8 | postgres7 | 
| 數(shù)據(jù)庫(kù)名稱(chēng) | MS Access | MS SQL Server | MySQL | Oracle 8 | PostgreSQL 7 | 
下面我們來(lái)看怎么使用ADODB連接數(shù)據(jù)庫(kù)。
1.連接MySQL數(shù)據(jù)庫(kù)
我們使用如下方法連接一個(gè)MySQL數(shù)據(jù)庫(kù):
require_coce('/libs/adodb/ADOdb.inc.php');
$conn = &ADONewConnection('mysql');
無(wú)論連接到一個(gè)什么類(lèi)型的數(shù)據(jù)庫(kù),我們都要使用ADONewConnection()函數(shù)來(lái)創(chuàng)建一個(gè)連接對(duì)象。
ADONewConnection接收一個(gè)選擇性參數(shù):<database name>,用以表示要連接的數(shù)據(jù)庫(kù)。如果沒(méi)有參數(shù)被指定,它將會(huì)使用ADOLoadCode() 內(nèi)部方法所載入的最后一個(gè)數(shù)據(jù)庫(kù)。
當(dāng)建立好一個(gè)連接對(duì)象后,我們還沒(méi)有真正連接上數(shù)據(jù)庫(kù),需要使用$conn->Connect()或者$conn->PConnect() 兩個(gè)方法,任選其一來(lái)完成真正的數(shù)據(jù)庫(kù)連接:
$conn -> Connect(DB_HOST,DB_USER,DB_PASSWORD,$database)
下面是創(chuàng)建一個(gè)mysql數(shù)據(jù)庫(kù)連接對(duì)象,并創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)連接:
$conn = ADONewConnection('mysql'); //創(chuàng)建一個(gè)ADODB連接對(duì)象
$mysql_obj = $conn->connect('localhost','root','passwd','dbname'); //連接到MySQL服務(wù)器
if (!$ora_obj) {
? ?echo $mysql_conn->ErrorMsg(); //顯示連接的錯(cuò)誤信息
? ?exit();
}else{
? ?$mysql_conn -> SetFetchMode(3);
}
Var_dump($mysql_obj);
這樣我們就創(chuàng)建好與本地MySQL服務(wù)器的連接了。可以看到,ADODB連接數(shù)據(jù)庫(kù)同樣很方便。
2.連接Oracle數(shù)據(jù)庫(kù)
如果要連接Oracle數(shù)據(jù)庫(kù)該如何寫(xiě)呢?結(jié)合表17-1,我們可以編寫(xiě)腳本如下:
require_once ("libs/adodb/adodb.inc.php");
$ora_conn = &ADONewConnection('oci8');
$ora_obj = $ora_conn -> Connect('localhost','oracle','oracle','oradb');
if (!$ora_obj) {
? ?echo $ora_conn->ErrorMsg();
? ?exit();
}else{
? ?$ora_conn -> SetFetchMode(3);
}
Var_dump($ora_conn);
注意:連接Oracle數(shù)據(jù)庫(kù)需要在PHP本地環(huán)境安裝好Oracle的客戶(hù)端驅(qū)動(dòng),以及連接文件設(shè)置。
其中,SetFetchMode(3)指的是取得記錄集時(shí),返回的是二維關(guān)聯(lián)數(shù)組。也可以使用字符形式,這樣更明了一些:
$mysql_conn->SetFetchMode(ADODB_FETCH_ASSOC);
17.4.4? ADODB的查詢(xún)方法
ADODB的查詢(xún)方法如下。
1.直接查詢(xún)
Excute()方法通過(guò)連接句柄執(zhí)行SQL查詢(xún),并返回一個(gè)變量,如下:
$sql='SELECT * FROM ice_cream WHERE flavor LIKE ?';
$res = $cnx->Execute($sql,array('Chocolate'));
2.緩存查詢(xún)
ADODB提供內(nèi)置的緩存機(jī)制,CacheExecute()方法用于每次查詢(xún)數(shù)據(jù)時(shí),會(huì)把相應(yīng)的結(jié)果序列化后保存到文件中,以后同樣的查詢(xún)語(yǔ)句就可以不用直接查詢(xún)數(shù)據(jù)庫(kù),而是從緩存文件中獲取,從而提高Web系統(tǒng)的性能。CacheExecute()方法的格式如下:
CacheExecute($ttc,$sql)
該方法以緩存的形式執(zhí)行一段查詢(xún),其中$ttc為緩存的時(shí)間,請(qǐng)看如下代碼:
$ADODB_CACHE_DIR = "/var/tmp/adodb_cache"; //緩存保存的文件目錄
$sql = "SELECT surname, age FROM employees"; //構(gòu)造一個(gè)查詢(xún)
$rs = &$db->CacheExecute(600,$sql);? // 緩存式查詢(xún),緩存將被保存600秒后更新
3.清除緩存
CacheFlush()
該方法用來(lái)清除所有ADODB數(shù)據(jù)庫(kù)的緩存。?
17.4.5? 移動(dòng)記錄集
記錄集(Record Set):從執(zhí)行的方法中返回指定的記錄,使用moveFirst()、moveLast()、moveNext()和move($n)方法訪問(wèn)記錄集中的一個(gè)指定記錄。例如:
$rs=$cnx->Execute('SELECT flavor,price FROM ice_cream');
$rs->MoveLast();
print "Flavor ".$rs->fields[0]." costs "
.$rs->fields[2]."/n";
$rs->MoveFirst();
//省略...
$rs->Move(2);
//省略...
$rs->MoveNext();
設(shè)置一個(gè)全局變量$ADODB_FETCH_MODE,從ADODB_FETCH_NUM(或從ADODB_FETCH_ASSOC返回)中取得數(shù)字索引(或關(guān)聯(lián)索引)數(shù)組。例如:
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC ;
$rs=$cnx->Execute('SELECT flavor,price FROM ice_cream');
print "<table>/n";
while (! $rs->EOF) {
??? print "<tr><td>".$rs->fields['flavor']}."</td>".
??? "<td>".$rs->fields['price']"."</td></tr>/n";
??? $rs->MoveNext();
}
print "</table>/n";
FetchObject()方法也是一個(gè)記錄集變量。
17.4.6? 使用ADODB生成HTML
ADODB的rs2html($res)函數(shù),它提供一個(gè)簡(jiǎn)單的方法,從$res變量中的記錄自動(dòng)生成HTML表格。
它在tohtml.inc.php中,使用時(shí)需要包含進(jìn)來(lái),如下代碼:
require 'adodb/tohtml.inc.php';? //引入rs2html函數(shù)
require 'adodb/adodb.inc.php';
//省略...
$rs = $cnx->Execute('SELECT flavor,calories,price FROM ice_cream');
rs2html($rs);
使用rs2html($res,'CLASS="myClass")這種格式,表示指定表格使用的myClass的樣式表類(lèi)進(jìn)行顯示。
17.4.7? 使用ADODB進(jìn)行分頁(yè)
ADODB_Pager(該方法定義在adodb-pager.inc.php中)提供一種簡(jiǎn)單分頁(yè)顯示記錄的方法。
require 'adodb/adodb.inc.php';
require 'adodb/adodb-pager.inc.php';
$pager=new ADODB_Pager($cnx,"SELECT id,flavor,price FROM ice_cream_big");
$pager->Render();
使用$pager->Render($num)來(lái)設(shè)置每次顯示的行數(shù),默認(rèn)值為10。
17.4.8 ?生成下拉選擇菜單
getMenu($selectName)方法將幫助我們生成一個(gè)<select>標(biāo)簽,即從記錄集中生成一個(gè)下拉菜單。其中,$selectName是該表單中select的name標(biāo)簽。例如:
$rs = $cnx->execute('SELECT flavor,id FROM ice_cream');
print $rs->GetMenu('which_flavor');
相關(guān)說(shuō)明如下:
?? getMenu($sN,$selected,$blank,$mult,$nm):其中,$selected (string)為默認(rèn)選擇的值/項(xiàng)。
?? $blank (boolean):默認(rèn)初始值或布爾值為true時(shí),下拉選項(xiàng)為空。
?? $mult (boolean):下拉菜單是否可以允許多選。
?? $nm (integer):設(shè)置菜單多重選擇的屬性,也就是默認(rèn)幾行。
17.4.9? ADODB開(kāi)發(fā)實(shí)例
為了能更好地理解和使用ADODB,下面一起做一個(gè)完整的實(shí)例。
首先準(zhǔn)備一個(gè)簡(jiǎn)單的表,名為“l(fā)ibrary”,用于保存書(shū)籍目錄。結(jié)構(gòu)與記錄內(nèi)容如下:
mysql> SELECT * FROM library;
+----+--------------------+---------------+
| id | title? ? ? ? ?? ??? | author? ? ? ?? |
+----+--------------------+---------------+
| 14 | ASP.NET 2.0網(wǎng)絡(luò)編程?| Dennis Lehane? |
| 15 | For Kicks? ? ? ?? ? | Dick Francis?? |
| 16 | XML and PHP? ? ?? ??| Vikram Vaswani |
| 17 | Where Eagles Dare? | Jack Higgins?? |
+----+--------------------+----------------+
在library表中,包含3個(gè)字段,分別為:
?? id——主鍵,用于保存書(shū)的序列號(hào);
?? title——用于保存書(shū)的標(biāo)題;
?? author——用于保存作者信息。
下面看使用PHP的傳統(tǒng)開(kāi)發(fā)方式,即使用PHP的MySQL API庫(kù)進(jìn)行編寫(xiě)的代碼,如下:
<?php
// 創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)連接
$connection = mysql_connect("localhost", "root", "passwd") or die ("Unable to connect!");
// 選擇數(shù)據(jù)庫(kù)
mysql_select_db("adodb") or die ("Unable to select database!");
// 構(gòu)建SQL和開(kāi)始查詢(xún)
$query = "SELECT * FROM library";
$result = mysql_query($query) or die ("Error in query: $query. " . mysql_error());
// 遍歷記錄集,并顯示字段的內(nèi)容
while ($row = mysql_fetch_row($result)){
?? echo "$row[1] - $row[2]/n";
}
// 顯示返回的記錄行數(shù)
echo "/n[" . mysql_num_rows($result) . " 行記錄被返回]/n";
// 關(guān)閉數(shù)據(jù)庫(kù)連接
mysql_close($connection);
?>
輸出結(jié)果如下:
ASP.NET 2.0網(wǎng)絡(luò)編程- Dennis Lehane
For Kicks - Dick Francis
XML and PHP - Vikram Vaswani
Where Eagles Dare - Jack Higgins
[4 行記錄被返回]
可以看到此例子比較簡(jiǎn)潔,連接到數(shù)據(jù)庫(kù),執(zhí)行查詢(xún),取回結(jié)果后顯示出來(lái)。
上述例子用mysql_fetch_row()的抽取功能,取得記錄后生成一個(gè)連續(xù)整數(shù)的索引數(shù)組,數(shù)據(jù)內(nèi)容分別對(duì)應(yīng)數(shù)據(jù)表中的字段。與此相似的還有mysql_fetch_assoc(),它生成一個(gè)關(guān)聯(lián)數(shù)組,或者mysql_fetch_object函數(shù),它生成一個(gè)對(duì)象(其屬性相當(dāng)于字段名)。
這段代碼是沒(méi)有任何問(wèn)題的,但如果我們想從MySQL遷移到PostgreSQL數(shù)據(jù)庫(kù)或者Oracle怎么辦呢?代碼需要重寫(xiě)了!這時(shí),就需要數(shù)據(jù)抽象層ADODB上場(chǎng)了。
我們把上例改用ADODB重新編寫(xiě),請(qǐng)看下面的代碼:
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)MySQL連接對(duì)象 
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
// 執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 遍歷返回的記錄集內(nèi)容,打印返回列的內(nèi)容:TITLE 和AUTHOR
while (!$result->EOF) {
?? echo $result->fields[1] . " - " . $result->fields[2] . "/n";
? ?? $result->MoveNext();
}
// 顯示返回的記錄行數(shù)
echo "/n[" . $result->RecordCount() . " 行記錄被返回]/n";
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
這個(gè)程序和上面程序的實(shí)現(xiàn)功能是一樣的,但是由于采用ADODB抽象層,而沒(méi)有采用PHP的本地API(mysql或mysqli擴(kuò)展),因此可以靈活地更換數(shù)據(jù)庫(kù)系統(tǒng),無(wú)論哪個(gè)數(shù)據(jù)庫(kù)以及如何更換,這段代碼都是可用的。
下面對(duì)上述代碼進(jìn)行詳細(xì)的解釋說(shuō)明。
首先,我們引用ADODB主類(lèi)文件:
<?php
? include_once("libs/adodb/adodb.inc.php");
實(shí)際上,ADODB庫(kù)并非只有這一個(gè)文件,事實(shí)上有超過(guò)30個(gè)不同的文件,負(fù)責(zé)驅(qū)動(dòng)不同的數(shù)據(jù)庫(kù)系統(tǒng)。我們不用擔(dān)心是否完全將類(lèi)包含完全,該文件會(huì)自動(dòng)識(shí)別和匹配當(dāng)前的PHP版本及數(shù)據(jù)庫(kù)系統(tǒng),并自動(dòng)包含相關(guān)的類(lèi)庫(kù)文件。
然后,創(chuàng)建ADODB的對(duì)象實(shí)例:
// 創(chuàng)建一個(gè)mysql連接對(duì)象
$DB = NewADOConnection("mysql");
通過(guò)對(duì)象的構(gòu)造參數(shù),告訴ADODB連接數(shù)據(jù)庫(kù),這里連接的是MySQL數(shù)據(jù)庫(kù)服務(wù)器,對(duì)于其他數(shù)據(jù)庫(kù),還可以相應(yīng)地使用"pgsql"或"oci8"。可以連接的數(shù)據(jù)庫(kù)及連接標(biāo)識(shí)參見(jiàn)表17-1。
接下來(lái),連接數(shù)據(jù)庫(kù),這是通過(guò)Connect()方法完成的,必須設(shè)置一套連接參數(shù):
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
以上代碼試圖打開(kāi)一個(gè)MySQL連接,3個(gè)參數(shù)分別為主機(jī)名、用戶(hù)名和密碼。
一旦Connect()方法建立連接后,就可以調(diào)用該對(duì)象的Execute()方法進(jìn)行SQL數(shù)據(jù)庫(kù)查詢(xún)。
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
當(dāng)查詢(xún)執(zhí)行成功后,則返回含有查詢(xún)結(jié)果的對(duì)象。特別說(shuō)明的是errormsg()方法,可以用來(lái)獲取查詢(xún)的一個(gè)錯(cuò)誤信息。
從返回的結(jié)果集中循環(huán)取值:
// 遍歷返回的記錄集內(nèi)容,打印返回列的內(nèi)容:TITLE 和AUTHOR
while (!$result->EOF) {
?? echo $result->fields[1] . " - " . $result->fields[2] . "/n";
?? $result->MoveNext();
}
在這種情況下,在循環(huán)體內(nèi),使用對(duì)象的movenext()方法進(jìn)行記錄的移動(dòng),每次循環(huán)打印后就移動(dòng)到下一條記錄。
取得記錄集后,可以使用recordcount()方法取得記錄的條數(shù)。
// 遍歷返回的記錄集內(nèi)容,打印返回列的內(nèi)容:TITLE 和AUTHOR
echo "/n[" . $result->RecordCount() . " 行記錄被返回]/n";
最后,使用Close()方法關(guān)閉數(shù)據(jù)庫(kù)的連接。
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
如果有人決定要更換數(shù)據(jù)庫(kù),唯一需要改變的是將上述腳本的連接改為新的數(shù)據(jù)庫(kù)名稱(chēng)和主機(jī)地址即可。
這就是數(shù)據(jù)抽象層最好的優(yōu)勢(shì)之一,它提供一些盡可能通用的方法,將與數(shù)據(jù)庫(kù)打交道的代碼隱藏在內(nèi)部,從而使PHP代碼簡(jiǎn)單、清爽、可維護(hù)性好,并且縮短開(kāi)發(fā)周期,以及擁有軟件包的整體感。
ADODB還提供了一些不同的方法處理結(jié)果記錄集。例如,我們可以取回結(jié)果集為一個(gè)關(guān)聯(lián)數(shù)組。請(qǐng)看如下腳本:
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "john", "doe", "adodb") or die("Unable to connect!");
// 將結(jié)果保存為一個(gè)關(guān)聯(lián)數(shù)組,也可以使用數(shù)值3
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 遍歷記錄集,顯示列的內(nèi)容:TITLE 和AUTHOR
while (!$result->EOF) {
?? echo $result->fields['title'] . " - " . $result->fields['author'] . "/n";
? ?? $result->MoveNext();
}
// 取得和顯示返回的記錄行數(shù)
echo "/n[" . $result->RecordCount() . " 行記錄被返回]/n";
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
在這個(gè)例子里,$ADODB_FETCH_MODE的值用于確定ADODB如何構(gòu)建結(jié)果記錄集。
你也可以把取得的行轉(zhuǎn)變?yōu)橐粋€(gè)對(duì)象,其屬性相當(dāng)于字段名,這就是ADODB的FetchNextObject()方法,請(qǐng)看如下腳本例子:
<?php
include("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接對(duì)象實(shí)例
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "john", "doe", "adodb") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 遍歷記錄集,顯示列的內(nèi)容:TITLE 和AUTHOR
while ($row = $result->FetchNextObject()) {
?? echo $row->TITLE . " - " . $row->AUTHOR . "/n";
}
// 取得和顯示返回的記錄行數(shù)
echo "/n[" . $result->RecordCount() . " 行記錄被返回]/n";
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
值得一提的是,FetchNextObject()方法可以自動(dòng)在記錄集中移動(dòng)到下一行,我們不需要再使用MoveNext()方法,當(dāng)?shù)竭_(dá)記錄集尾部時(shí),該方法返回false。
1.GetAll方法
我們可以使用GetAll方法代替Execute()方法,該方法返回的結(jié)果為一個(gè)二維關(guān)聯(lián)數(shù)據(jù),這樣可以使用foreach或for循環(huán)語(yǔ)句處理,非常方便。另外,GetAll取得的數(shù)組與Smarty模板的foreach配合得非常好。
我們一起看下面的腳本例子:
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "root", "library") or die("Unable to connect");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->GetAll($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 清除無(wú)用的對(duì)象
$db->Close();
// 可以使用print_r打印該數(shù)組的內(nèi)容
// print_r($result); exit(0);
// 遍歷記錄集,顯示列的內(nèi)容:TITLE 和AUTHOR
foreach ($result as $row){
?? echo $row[1] . " - " . $row[2] . "/n";
}
// 取得和顯示返回的記錄行數(shù)
echo "/n[" . sizeof($result) . " 行記錄被返回]/n";
?>
GetAll()方法取得記錄集后,產(chǎn)生一個(gè)二維數(shù)組,類(lèi)似于下面的樣子:
Array
(
[0] => Array
? ? ? ? (
? ? ? ? ? ? [0] => 14
? ? ? ? ? ? [id] => 14
? ? ? ? ? ? [1] => Mystic River
? ? ? ? ? ? [title] => Mystic River
? ? ? ? ? ? [2] => Dennis Lehane
? ? ? ? ? ? [author] => Dennis Lehane
? ? ? ? )
? ? [1] => Array
? ? ? ? (
? ? ? ? ? ? [0] => 15
? ? ? ? ? ? [id] => 15
? ? ? ? ? ? [1] => For Kicks
? ? ? ? ? ? [title] => For Kicks
? ? ? ? ? ? [2] => Dick Francis
? ? ? ? ? ? [author] => Dick Francis
? ? ? ? )
? ? ?? //下略
)
我們?cè)跀?shù)組一章,提到過(guò)這類(lèi)混合數(shù)組最適合用foreach來(lái)處理。這種方法是對(duì)Execute()方法的補(bǔ)充或替代,尤其適合在遍歷查詢(xún)整個(gè)表時(shí)使用。
另外,ADODB還提供取得一條記錄的方法:GetOne()。
2.GetOne()方法
ADODB有個(gè)比較直接的方法可以比較方便地檢測(cè)某條記錄是否存在,那就是它的GetOne($sql)方法。
該方法返回查詢(xún)記錄的第1條第1個(gè)字段名的值,如果執(zhí)行過(guò)程中出現(xiàn)錯(cuò)誤,則返回布爾值false。
我們可以檢測(cè)這個(gè)值是否存在:
<?php
Include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", “root”, “passwd”, “adodb”) or die("Unable to connect!");
$rs = $db->GetOne("SELECT * FROM library WHERE id='$id'");
if($rs){
? echo '記錄存在';
}else {
?? echo '記錄不存在';
}
?>
不過(guò)這樣有一個(gè)問(wèn)題是,如果數(shù)據(jù)表中id=$id的記錄有多條,不僅僅要知道是否存在有這樣一條記錄,還要把這條記錄提取出來(lái),則可以使用ADODB的GetRow()方法。
3.GetRow()方法
<?php
Include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", “root”, “passwd”, “adodb”) or die("Unable to connect!");
$rs = $db->GetRow("SELECT * FROM library WHERE id='$id'");
if(is_array($rs)){
?? echo '記錄存在';
?? print_r($rs);
} else {
?? echo '記錄不存在';
}
?>
需要注意的是,GetOne($sql) 和 GetRow($sql) 都能得到一條特定的記錄,或者得到該記錄不存在的信息,但是如果符合查詢(xún)條件的記錄存在多條時(shí),則這兩個(gè)方法只傳回第一條記錄,其他的都自動(dòng)拋棄。
如果只要得到查詢(xún)結(jié)果的行數(shù),則可以使用結(jié)果集方法中的RecordCount()方法。
4.取得返回的記錄行數(shù)
ADODB還提供了一批實(shí)用功能,如在進(jìn)行查詢(xún)時(shí),提供了非常有用的RecordCount() 和FieldCount()方法,分別返回記錄的數(shù)量和字段的數(shù)量,以下是應(yīng)用這兩個(gè)方法的例子。
<?php
include("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", “root”, “passwd”, “adodb”) or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 取得和顯示返回的記錄行數(shù)
echo $result->RecordCount() . " 行記錄被返回/n";
// 取得和顯示返回的字段個(gè)數(shù)
echo $result->FieldCount() . " 個(gè)字段被返回/n";
// clea up
$db->Close();
?>
我們可以使用FetchField()方法取得字段的信息,其中含有該字段的詳細(xì)資料,包括名稱(chēng)和類(lèi)型等,請(qǐng)看如下的腳本例子。
<?php
include("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql"); 
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 取得記錄集中字段的結(jié)構(gòu)信息
for($x=0; $x<$result->FieldCount(); $x++){
?? print_r($result->FetchField($x));
}
// 清理無(wú)用的對(duì)象
$db->Close();
?>
下面輸出的是有關(guān)id字段的結(jié)構(gòu)信息。
stdClass myMagicbject
(
? ? [name] => id
? ? [table] => library
? ? [def] =>
? ? [max_length] => 3
? ? [not_null] => 1
? ? [primary_key] => 1
? ? [multiple_key] => 0
? ? [unique_key] => 0
? ? [numeric] => 1
? ? [blob] => 0
? ? [type] => int
? ? [unsigned] => 1
? ? [zerofill] => 0
? ? [binary] =>
)
?
5.其他相關(guān)方法
當(dāng)執(zhí)行一個(gè)INSERT查詢(xún)時(shí),如果該表的主鍵是一個(gè)自動(dòng)增量的字段,則可以使用ADODB的insert_id()方法,來(lái)獲得最后數(shù)據(jù)插入時(shí)自動(dòng)產(chǎn)生的增量值。
<?php
include_once(“l(fā)ibs/adodb/adodb.inc.php”);
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", “root”, “root”, “adodb”) or die("Unable to connect!");
// 構(gòu)造并執(zhí)行INSERT插入操作
$title = $db->qstr("PHP5與MySQL5 Web開(kāi)發(fā)技術(shù)詳解");
$author = $db->qstr("杜江");
$query = "INSERT INTO library (title, author) VALUES ($title, $author)";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 顯示插入的記錄號(hào)
if ($result){
?? echo "最后插入的記錄ID: " . $db->Insert_ID();
}
// 清理無(wú)用的對(duì)象
$db->Close();
?>
腳本中的qstr()方法,功能是過(guò)濾SQL查詢(xún)中的非法字符。
執(zhí)行后,即無(wú)論查詢(xún)(SELECT)、刪除(DELETE)或修改(UPDATE)數(shù)據(jù),如果想知道是否對(duì)表有影響,可以使用affected_rows()方法,它可以告訴我們操作后有多少(記錄)行受到了影響。請(qǐng)看下面的腳本例子:
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", “root”, “root”, “adodb”) or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "DELETE FROM library WHERE author = 'J. Luser'";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 取得和顯示執(zhí)行后影響的記錄行數(shù)
if ($result){
?? echo $db->Affected_Rows() . " 行已被刪除";
}
// 清理無(wú)用的對(duì)象
$db->Close();
?>
6.限制查詢(xún)結(jié)果
上面我們討論了如何通過(guò)使用一個(gè)數(shù)據(jù)庫(kù)庫(kù)函數(shù)使應(yīng)用程序更簡(jiǎn)潔,更易于移植。比如從MS SQL Server轉(zhuǎn)移到MySQL,在MS SQL Server中使用指令“SELECT TOP 15 name FROM employee”取得數(shù)據(jù)的前15條,可在MySQL中卻不支持這種寫(xiě)法,而要寫(xiě)成:SELECT name FROM employee LIMIT 15。
它似乎對(duì)我們敲響了警鐘,應(yīng)該停止在查詢(xún)語(yǔ)句中使用非標(biāo)準(zhǔn)SQL指令,而去認(rèn)真地學(xué)習(xí)標(biāo)準(zhǔn)的SQL。
幸運(yùn)的是,ADODB有一個(gè)處理 LIMIT的方法:SelectLimit(),這樣我們就根本不用管連接的是MySQL還是MS SQL Server,ADODB會(huì)在底層為我們自動(dòng)轉(zhuǎn)換,請(qǐng)見(jiàn)下面的腳本例子:
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
// 我們要取得5行記錄,從符合記錄的第3行開(kāi)始取
$query = "SELECT * FROM library";
$result = $db->SelectLimit($query, 5, 3) or die("Error in query: $query. " . $db->ErrorMsg());
// 遍歷記錄集
while (!$result->EOF) {
?? echo $result->fields[1] . " - " . $result->fields[2] . "/n";
? ?$result->MoveNext();
}
// 清理無(wú)用的對(duì)象
$db->Close();
?>
在這個(gè)例子中,selectlimit()方法類(lèi)似于MySQL的LIMIT語(yǔ)句,可用于控制從某行開(kāi)始查詢(xún),到某行的結(jié)果,從而取得我們指定的記錄集。
我們可以利用ADODB提供的MetaDatabases()方法取得當(dāng)前服務(wù)器中所有數(shù)據(jù)庫(kù)的清單。還有一個(gè)方法和它很類(lèi)似,即使用MetaTables()方法可以取得當(dāng)前庫(kù)中所有表的清單。請(qǐng)看下面的例子:
<?php
include(“l(fā)ibs/adodb/adodb.inc.php”);
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
// 取得數(shù)據(jù)列表
echo "數(shù)據(jù)庫(kù):/n";
foreach($db->MetaDatabases() as $d){
?? echo "* $d/n";?? 
}
// 取得數(shù)據(jù)表清單
echo "/n當(dāng)前數(shù)據(jù)庫(kù)下的表:/n";
foreach($db->MetaTables() as $table){
?? echo "* $table/n";?? 
}
// 清理無(wú)用的對(duì)象
$db->Close();
?>
7.快速存取
有時(shí),我們需要對(duì)一些不同的值做一些特殊的查詢(xún),比如一系列的INSERT(插入)語(yǔ)句。ADODB類(lèi)提供了兩個(gè)方法,可以使我們既節(jié)約時(shí)間又節(jié)省系統(tǒng)的開(kāi)銷(xiāo),請(qǐng)看如下示例:
<?php
include(“l(fā)ibs/adodb/adodb.inc.php”);
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
// 構(gòu)造準(zhǔn)備查詢(xún),使用參數(shù)綁定
$query = $db->Prepare("INSERT INTO library (title, author) VALUES (?, ?)");
// 從CSV 中取得要插入的標(biāo)題和作者名稱(chēng)
$data = file("./book_list.csv");
// 遍歷該文件,并執(zhí)行插入操作
foreach ($data as $l){
?? $arr = explode(",", $l);
?? // 插入值并綁定準(zhǔn)備語(yǔ)句
?? $result = $db->Execute($query, array($arr[0], $arr[1])) or die("Error in query: $query. " . $db->ErrorMsg());
}
// 清理無(wú)用的對(duì)象
$db->Close;
?>
prepare()函數(shù),把一個(gè)SQL查詢(xún)作為參數(shù),讀取一個(gè)查詢(xún),但并不立即執(zhí)行。prepare()返回一個(gè)句柄給一個(gè)prepare查詢(xún),當(dāng)保存和傳遞給Execute()方法后,則立即執(zhí)行該查詢(xún)。
?
8.處理事務(wù)
處理事務(wù)是許多應(yīng)用程序的一個(gè)重要的特征(比如,錢(qián)從你的賬戶(hù)轉(zhuǎn)出,然后轉(zhuǎn)入到某個(gè)人的賬戶(hù)中。只要其中任意一步操作失敗,這整個(gè)過(guò)程都必須被認(rèn)定為失敗。不然,錢(qián)被劃出,而沒(méi)有進(jìn)對(duì)方的賬戶(hù);或者,錢(qián)沒(méi)有劃出,但對(duì)方賬戶(hù)無(wú)端多了一筆錢(qián))。
處理事務(wù)可以在代碼級(jí)上進(jìn)行機(jī)警地管理控制。常數(shù)錯(cuò)誤檢查被用來(lái)判斷執(zhí)行COMMIT(事務(wù)的所有各項(xiàng)都正確,執(zhí)行正確,結(jié)束事務(wù))還是執(zhí)行ROLLBACK(事務(wù)中有錯(cuò)誤,所有改動(dòng)需要恢復(fù)原來(lái)狀況)。
現(xiàn)在的數(shù)據(jù)庫(kù)系統(tǒng)絕大多數(shù)都支持事務(wù),如MySQL、Oracle、MS SQL Server等,ADODB提供一個(gè)非常好的功能,能夠讓你更透明地使用這一特性。請(qǐng)看下面的例子:
<?php
include(“l(fā)ibs/adodb/adodb.inc.php”);
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", “root”, “root”, “adodb”) or die("Unable to connect!");
//關(guān)閉auto-commit自動(dòng)提交事務(wù)
// 開(kāi)始事務(wù)處理語(yǔ)句塊
$db->BeginTrans();
// 第一次查詢(xún)
$query = "INSERT INTO library (title, author) VALUES ('測(cè)試用書(shū)', '佚名')";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
//使用第一次查詢(xún)返回的ID號(hào)
if ($result){
?? $id = $db->Insert_ID();
?? $query = "INSERT INTO purchase_info (id, price) VALUES ($id, 'RMB 31.9')";
?? $result = $db->Execute($query)
?or die("Error in query: $query. " . $db->ErrorMsg());
}
// 如果操作成功
if ($result){
?? // 事務(wù)提交
?? $db->CommitTrans();
}// 否則回滾
else{
?? $db->RollbackTrans();
}
// 清理無(wú)用的對(duì)象
$db->Close;
?>
該腳本首先需要關(guān)掉數(shù)據(jù)庫(kù)的auto commit功能,通過(guò)begintrans()方法來(lái)處理,這種方法也標(biāo)志著一個(gè)事務(wù)的開(kāi)始。可以使用CommitTrans()或RollbackTrans()函數(shù)來(lái)處理操作,一旦auto commit已經(jīng)關(guān)掉,你就可以任意執(zhí)行所需要的查詢(xún),確認(rèn)事務(wù)的查詢(xún)執(zhí)行無(wú)誤并完畢后,由我們自己決定何時(shí)執(zhí)行commit操作。
每一次執(zhí)行Execute()事務(wù)塊后,它會(huì)返回一個(gè)布爾值,告訴我們是否成功地執(zhí)行了查詢(xún)。可以跟蹤到這個(gè)值,以及使用的時(shí)間,以決定是否要進(jìn)行整個(gè)交易行為。一旦你相信一切都沒(méi)問(wèn)題,則告訴數(shù)據(jù)庫(kù)committrans()方法;如果發(fā)現(xiàn)有錯(cuò)誤發(fā)生,則可以進(jìn)行回滾操作——執(zhí)行rollbacktrans()方法。
值得注意的是,注意您的數(shù)據(jù)庫(kù)類(lèi)型是否支持這些事務(wù)函數(shù),前面已經(jīng)說(shuō)過(guò),MySQL的InnoDB類(lèi)型表支持事務(wù),但是MyISAM類(lèi)型并不支持。
9.使用緩存查詢(xún)
在一個(gè)動(dòng)態(tài)頁(yè)面中,如果其中的一個(gè)查詢(xún)指令很少改變且頻繁被執(zhí)行,我們則可以使用ADODB的緩存功能,可以將查詢(xún)指令的結(jié)果緩存成靜態(tài)文件,從而提高PHP腳本的性能。
當(dāng)試圖通過(guò)緩存來(lái)提高你的應(yīng)用程序的性能之前,建議先去優(yōu)化查詢(xún)指令再開(kāi)始本操作,這樣才會(huì)起到事半功倍之效果。
ADODB最棒的功能就是提供查詢(xún)緩存的功能。緩存可以大大改善應(yīng)用程序的性能,尤其是網(wǎng)站系統(tǒng),因?yàn)榇蟛糠钟脩?hù)都是在瀏覽網(wǎng)站,數(shù)據(jù)庫(kù)完成的任務(wù)多半是查詢(xún)(SELECT操作)。為了更好地理解與應(yīng)用緩存查詢(xún)的功能,我們來(lái)看下面的腳本例子。
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "root", "adodb") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 遍歷返回的記錄集,顯示列數(shù)據(jù)的內(nèi)容 TITLE 和 AUTHOR
while (!$result->EOF) {
?? echo $result->fields[1] . " - " . $result->fields[2] . "/n";
? ?? $result->MoveNext();
}
// 顯示取得的記錄行數(shù)
echo "/n[" . $result->RecordCount() . " 行記錄被返回]/n";
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
這段代碼使用ADODB進(jìn)行一個(gè)SELECT操作。比如說(shuō),這就是您的網(wǎng)站,平均有每分鐘5000次的點(diǎn)擊(PV,Page View)量,那么數(shù)據(jù)庫(kù)系統(tǒng)每小時(shí)至少要被查詢(xún)3萬(wàn)次以上,可以想象,這對(duì)我們的MySQL數(shù)據(jù)庫(kù)的負(fù)載是相當(dāng)繁重的。
因此ADODB提供了緩存的功能,可以將經(jīng)常查詢(xún)的結(jié)果保存起來(lái),進(jìn)而降低數(shù)據(jù)庫(kù)服務(wù)器的負(fù)荷,同時(shí)也向用戶(hù)提供更快速的內(nèi)容響應(yīng)。
下面是修改上面的腳本,改為使用CacheExecute來(lái)進(jìn)行緩存查詢(xún)的示例:
<?php
include("libs/adodb/adodb.inc.php");
//設(shè)置緩存保存的路徑,.表示當(dāng)前目錄
$ADODB_CACHE_DIR = '.'; //為了管理方便,實(shí)際開(kāi)發(fā)環(huán)境請(qǐng)指向到獨(dú)立的目錄中,如/tmp/adodb
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT * FROM library";
$result = $db->CacheExecute(300,$query) or die("Error in query: $query. " . $db->ErrorMsg());
// 遍歷返回的記錄集,顯示列數(shù)據(jù)的內(nèi)容 TITLE 和 AUTHOR
while (!$result->EOF) {
?? echo $result->fields[1] . " - " . $result->fields[2] . "/n";
? ?? $result->MoveNext();
}
// 取得和顯示返回的記錄行數(shù)
echo "/n[" . $result->RecordCount() . " 行記錄被返回]/n";
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
CacheExecute()方法的第一個(gè)參數(shù)是緩存文件(緩存文件被命名為adodb_*.cache)將被保留的時(shí)間,以秒計(jì)時(shí);第二個(gè)參數(shù)是SQL聲明。第一個(gè)參數(shù)是可選擇的,若沒(méi)有限定時(shí)間,默認(rèn)值是3600秒,也就是1個(gè)小時(shí)。
值得一提的是,使用CacheExcute()方法時(shí),需要將php.ini中的參數(shù)magic_quotes_runtime設(shè)為0。
也可以根據(jù)需要,在程序運(yùn)行時(shí)動(dòng)態(tài)修改它的值:
set_magic_quotes_runtime(0);
注意:將上述代碼放到調(diào)用數(shù)據(jù)庫(kù)的指令之前,我們還可以在任何時(shí)候,通過(guò)調(diào)用CacheFlush()來(lái)清除過(guò)時(shí)的緩存。
10.生成下拉列表菜單
ADODB特意為Web開(kāi)發(fā)任務(wù)提供幾個(gè)通用的方法。其中,最有用的是GetMenu()方法,通過(guò)抽取數(shù)據(jù)庫(kù)的記錄集,自動(dòng)地生成表單及菜單列表框。
下面介紹的就是從數(shù)據(jù)庫(kù)動(dòng)態(tài)構(gòu)建下拉菜單(Option)的例子。
<html>
<head></head>
<body>
<?php
include_once("libs/adodb/adodb.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "root", "library") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT title, id FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
//顯示HTML下拉列表菜單
echo $result->GetMenu("library", '', false);
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
</body>
</html>
GetMenu()方法需要傳入?yún)?shù),用來(lái)控制列表框的行為。上例中第一個(gè)參數(shù)是列表框的名字(這個(gè)例子為“l(fā)ibrary”);第二個(gè)參數(shù)是顯示時(shí)默認(rèn)的值,可以為空,從第一個(gè)記錄開(kāi)始;第三個(gè)參數(shù),指定列表框的項(xiàng)目是否為空;第四個(gè)參數(shù),控制是否允許用戶(hù)多選。
上例的顯示結(jié)果如下:
<select name="library" >
<option value="15">Mystic River</option>
<option value="16">Where Eagles Dare</option>
<option value="17">XML and PHP</option>
</select>
可以看到,該列表菜單內(nèi)容是從library表抽取的記錄,列表框的名字為“l(fā)ibrary”,在記錄集中,ID是菜單選項(xiàng)的值,名稱(chēng)為菜單框顯示的元素。
由此可以看出,GetMenu()方法可以大幅度簡(jiǎn)化Web開(kāi)發(fā)任務(wù),大大減少代碼量。
11.輸出到文件
ADODB還允許我們將記錄輸出為一個(gè)不同形式的文件:如逗號(hào)分隔符CSV文件,制表符表格,甚至于HTML形式的表格。
這些功能屬于ADODB的附屬功能,在使用時(shí)需要包含相關(guān)ADODB類(lèi)文件,下面是樣例的內(nèi)容。
<?php
include("libs/adodb/adodb.inc.php");
// 包含轉(zhuǎn)換方法的文件
include_once("libs/adodb/toexport.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "library") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT title, id FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 返回一個(gè)CSV字符串
echo rs2csv($result);
// 關(guān)閉數(shù)據(jù)庫(kù)的連接
$db->Close();
?>
輸出結(jié)果如下:
title,id
Mystic River,15
Where Eagles Dare,16
XML and PHP,17
我們也可以去除結(jié)果中第一行,即字段的名稱(chēng),使用腳本格式如下:
// 返回一個(gè) CSV 字符串
echo rs2csv($result, false);
腳本的輸出結(jié)果將沒(méi)有字段名稱(chēng),如下:
Mystic River,15
Where Eagles Dare,16
XML and PHP,17
ADODB還提供生成制表符或分隔符文件功能,使用rs2tab()方法:
<?php
include("libs/adodb/adodb.inc.php");
// 包含轉(zhuǎn)換方法的文件
include("toexport.inc.php");
//創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "root", "library") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT title, id FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 返回一個(gè)TAB制表符分隔的字符串
echo rs2tab($result);
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
顯示結(jié)果如下:
title?? id
Mystic River?? 15
Where Eagles Dare?? 16
XML and PHP?? 17
ADODB還提供生成HTML表格的功能,使用rs2html()方法:
<html>
<head></head>
<body>
<?php
include_once(“l(fā)ibs/adodb/adodb.inc.php”);
// 包含轉(zhuǎn)換方法的文件
include_once("libs/adodb/tohtml.inc.php");
// 創(chuàng)建一個(gè)mysql連接實(shí)例對(duì)象
$db = NewADOConnection("mysql");
// 打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
$db->Connect("localhost", "root", "passwd", "library") or die("Unable to connect!");
// 構(gòu)造并執(zhí)行一個(gè)查詢(xún)
$query = "SELECT title, id FROM library";
$result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
// 返回一個(gè)HTML格式的表格
echo rs2html($result);
// 關(guān)閉數(shù)據(jù)庫(kù)連接
$db->Close();
?>
</body>
</html>
輸出結(jié)果如下:
總結(jié)
 
                            
                        - 上一篇: 短信java_Java发送手机短信(附代
- 下一篇: [4G5G专题-12]:功能-LTE载波
