ADODB類(lèi)使用
MySQL的例子
PHP中最通用的數(shù)據(jù)庫(kù)是MySQL,所以我想你會(huì)喜歡下面的程序代碼,它連結(jié)到 localhost 的 MySQL 服務(wù)器,數(shù)據(jù)庫(kù)名稱(chēng)是 mydab,并且執(zhí)行一個(gè) SQL 的 select 指令查詢(xún),查詢(xún)結(jié)果會(huì)一列列地印出來(lái)。
$db = mysql_connect("localhost", "root", "password");
mysql_select_db("mydb",$db);
$result = mysql_query("SELECT * FROM employees",$db);
if ($result === false) die("failed");
while ($fields = mysql_fetch_row($result)) {
for ($i=0, $max=sizeof($fields); $i < $max; $i++) {
print $fields[$i].' ';
}
print "<br>n";
}
上列的程序代碼用顏色標(biāo)出分段,第一段是連結(jié)的部分,第二段是執(zhí)行SQL指令,最后一段則是顯示字段,while循環(huán)掃描結(jié)果的每一列,而for循環(huán)掃描到每列的字段。
接下來(lái)是以ADODB的程序代碼得到同樣的結(jié)果:
include("adodb.inc.php");
$db = NewADOConnection('mysql');
$db->Connect("localhost", "root", "password", "mydb");
$result = $db->Execute("SELECT * FROM employees");
if ($result === false) die("failed");
while (!$result->EOF) {
for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
print $result->fields[$i].' ';
$result->MoveNext();
print "<br>n";
}
現(xiàn)在改成指向Oracle數(shù)據(jù)庫(kù),程序代碼只要修改第二行成為 NewADOConnection('oracle'),讓我們看一下完整的程序代碼...
與數(shù)據(jù)庫(kù)連結(jié)
include("adodb.inc.php");
$db = NewADOConnection('mysql');
$db->Connect("localhost", "root", "password", "mydb");
連結(jié)的程序代碼比起原來(lái)MySQL的程序代碼有老練一些,因?yàn)槲覀冋切枰暇毿?。在ADODB我們使用對(duì)象導(dǎo)向的方法來(lái)管理多樣數(shù)據(jù)庫(kù)的復(fù)雜性,我們用不同類(lèi)(class)來(lái)控制不同數(shù)據(jù)庫(kù)。假如你不熟悉對(duì)象導(dǎo)向程序設(shè)計(jì),別擔(dān)心!所有的復(fù)雜事情都隱藏在 NewADOConnection() 函數(shù)之后。
為了節(jié)省內(nèi)存,我們只加載與你所連結(jié)數(shù)據(jù)庫(kù)相關(guān)的PHP程序代碼,我們通過(guò)調(diào)用NewADOConnection(databasedriver)來(lái)完成這件事,合法的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序包含 mysql,mssql,oracle,oci8,postgres,sybase,vfp,access,ibase 以及許多其它的驅(qū)動(dòng)程序。
接著我們通過(guò)調(diào)用 NewADOConnection() 來(lái)從連結(jié)類(lèi)別產(chǎn)生一個(gè)新的對(duì)象實(shí)體,最后我們使用 $db->Connect() 來(lái)連結(jié)數(shù)據(jù)庫(kù)。
執(zhí)行SQL指令
$result = $db->Execute("SELECT * FROM employees");
if ($result === false) die("failed");
直接傳送SQL指令到服務(wù)器,當(dāng)成功執(zhí)行之后,Execute()將傳回一個(gè)recordset對(duì)象,你可以如同上面所列來(lái)檢查$result。
一個(gè)初學(xué)者容易混淆的議題是,在ADODB有兩種類(lèi)型的對(duì)象,連結(jié)對(duì)象以及recordset對(duì)象,我們何時(shí)用這些對(duì)象呢?
連結(jié)對(duì)象($db)是負(fù)責(zé)連結(jié)數(shù)據(jù)庫(kù),格式化你的SQL查詢(xún)。而recordset對(duì)象($result)則是負(fù)責(zé)擷取結(jié)果并將響應(yīng)數(shù)據(jù)規(guī)格化成文字或數(shù)組。
唯一我需要增加的事情是,ADODB提供許多有用的函數(shù)來(lái)讓INSERT及UPDATE指令更容易些,這點(diǎn)我們?cè)谶M(jìn)階的章節(jié)會(huì)提到。
擷取資料
while (!$result->EOF) {
for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
print $result->fields[$i].' ';
$result->MoveNext();
print "<br>n";
}
前面取得數(shù)據(jù)的范例很像從檔案讀數(shù)據(jù),在每一行我們首先檢查是否到了檔案的結(jié)尾(EOF),若還沒(méi)到結(jié)尾,循環(huán)掃過(guò)每列中的字段,然后移到下一行(MoveNext)接著重復(fù)同樣的事情。
$result->fields[]數(shù)組是由PHP數(shù)據(jù)庫(kù)延伸系統(tǒng)所產(chǎn)生的,有些數(shù)據(jù)庫(kù)延伸系統(tǒng)并不會(huì)以字段名稱(chēng)建立該數(shù)組的索引,要強(qiáng)迫以名稱(chēng)排序索引該數(shù)組,使用$ADODB_FETCH_MODE的通用變量。
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs1 = $db->Execute('select * from table');
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); // shows array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); // shows array(['col1']=>'v0',['col2'] =>'v1')
如同你所見(jiàn)的上面例子,兩個(gè)recordset儲(chǔ)存并使用不同的取用模式,當(dāng)recordset由Execute()產(chǎn)生后再設(shè)定$ADODB_FETCH_MODE。
ADOConnection
連結(jié)到數(shù)據(jù)庫(kù)的對(duì)象,執(zhí)行SQL指令并且有一組工具函數(shù)來(lái)標(biāo)準(zhǔn)格式化SQL指令,比如關(guān)聯(lián)與日期格式等指令。
其它有用的函數(shù)
$recordset->Move($pos)卷動(dòng)目前的數(shù)據(jù)列,ADODB支持整個(gè)數(shù)據(jù)庫(kù)往前卷動(dòng),有一些數(shù)據(jù)庫(kù)并不支持往后的卷動(dòng),這倒不會(huì)是個(gè)問(wèn)題,因?yàn)槟隳軌蛴脮捍婕o(jì)錄到快取來(lái)仿真往后卷動(dòng)。
$recordset->RecordCount()傳回SQL指令存取到的紀(jì)錄筆數(shù),有些數(shù)據(jù)庫(kù)會(huì)因?yàn)椴恢С侄鴤骰?1。
$recordset->GetArray()以數(shù)組的方式傳回結(jié)果。
rs2html($recordset)函數(shù)將傳進(jìn)的recordset轉(zhuǎn)為HTML的表格格式。下例中以粗體字顯示相關(guān)用法:
include('adodb.inc.php');
include('tohtml.inc.php'); /* includes the rs2html function */
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
$rs = $conn->Execute('select * from table');
rs2html($rs); /* recordset to html table */
還有許多其它有用的函數(shù)列示在文件之中,可從下列網(wǎng)址查得 http://php.weblogs.com/adodb_manual
進(jìn)階題材
新增及更新
假設(shè)你要新增下列數(shù)據(jù)到數(shù)據(jù)庫(kù)中。
ID = 3
TheDate=mktime(0,0,0,8,31,2001) /* 31st August 2001 */
Note= sugar why don't we call it off
當(dāng)你改用別的數(shù)據(jù)庫(kù),可能就沒(méi)辦法新增數(shù)據(jù)。
第一個(gè)問(wèn)題是,每一個(gè)數(shù)據(jù)庫(kù)各自有不同的內(nèi)定日期格式,MySQL使用 YYYY-MM-DD 格式,而其它數(shù)據(jù)庫(kù)則有不同的內(nèi)定格式,ADODB提供DBDate()函數(shù)來(lái)轉(zhuǎn)換不同數(shù)據(jù)庫(kù)之間的日期內(nèi)定格式。
次一個(gè)問(wèn)題是單引號(hào)(don't)的表示法,在MySQL可以直接使用單引號(hào)(don't),但在其它數(shù)據(jù)庫(kù)如Sybase、Access、 Microsoft SQL Server,則用兩個(gè)單引號(hào)表示(don''t),qstr()函數(shù)可以解決此問(wèn)題。
我們?nèi)绾问褂眠@些函數(shù)?就像這樣:
$sql = "INSERT INTO table (id, thedate,note) values ("
. $ID . ','
. $db->DBDate($TheDate) .','
. $db->qstr($Note).")";
$db->Execute($sql);
ADODB還有$connection->Affected_Rows()函數(shù),傳回受最后update或delete指令影響的數(shù)據(jù)列數(shù),及$recordset->Insert_ID()函數(shù),傳回最后因insert指令而自動(dòng)產(chǎn)生的數(shù)據(jù)列編號(hào),預(yù)先提醒大家,沒(méi)有任何數(shù)據(jù)庫(kù)有提供這兩個(gè)函數(shù)。
MetaTypes
你可以得到關(guān)于字段的更多信息,透過(guò)recordset的方法FetchField($fieldoffset)傳回對(duì)象的3個(gè)屬性:name,type,max_length。
舉例說(shuō)明:
$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
結(jié)果$f0->name的內(nèi)容是'adata',$f0->type將是'date',假如max_length不知道,其內(nèi)容將會(huì)是-1。
處理不同數(shù)據(jù)庫(kù)的一個(gè)問(wèn)題是,每一個(gè)數(shù)據(jù)庫(kù)對(duì)于相同的數(shù)據(jù)型態(tài)會(huì)有不同的稱(chēng)呼,比如timestamp型態(tài)在某數(shù)據(jù)庫(kù)中稱(chēng)為datetime,而另一個(gè)數(shù)據(jù)庫(kù)則稱(chēng)為time,所以ADODB提供MetaType($type,$max_length)函數(shù)來(lái)標(biāo)準(zhǔn)化下列的數(shù)據(jù)型態(tài):
C: character and varchar types
X: text or long character (eg. more than 255 bytes wide).
B: blob or binary image
D: date
T: timestamp
L: logical (boolean)
I: integer
N: numeric (float, double, money)
在前面的例子中,
$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
$type = $recordset->MetaType($f0->type, $f0->max_length);
print $type; /* should print 'D' */
Select指令的Limit及Top支持
ADODB有個(gè)$connection->SelectLimit($sql,$nrows,$offset)函數(shù)讓你擷取recordset的部分集合,這是采用Microsoft產(chǎn)品中的SELECT TOP用法,及PostgreSQL與MySQL中的SELECT...LIMIT用法的優(yōu)點(diǎn),即使原來(lái)的數(shù)據(jù)庫(kù)并沒(méi)有提供此用法,本函數(shù)也仿真提供該使用方式。
快取支援
ADODB允許你在你的檔案系統(tǒng)中暫存recordset的數(shù)據(jù),并且在$connection->CacheExecute($secs2cache,$sql)及 $connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset)等設(shè)定的時(shí)間間隔到達(dá)之后,才真正去做數(shù)據(jù)庫(kù)的查詢(xún)以節(jié)省時(shí)間。
PHP4 Session支持
ADODB也支持PHP4 session handler,你可以存放你的session變量在數(shù)據(jù)庫(kù)中,相關(guān)功能請(qǐng)參考 http://php.weblogs.com/adodb-sessions
鼓勵(lì)商業(yè)使用
假如你計(jì)劃寫(xiě)商用的PHP應(yīng)用軟件來(lái)銷(xiāo)售,你也可以使用ADODB,我們依據(jù)GPL來(lái)出版ADODB,也就是說(shuō)你可以合法地在商用應(yīng)用軟件中引用,并保有你程序代碼的所有權(quán)。強(qiáng)烈地鼓勵(lì)A(yù)DODB的商業(yè)應(yīng)用,我們自己內(nèi)部也正以這個(gè)理由如此使用中。
相關(guān)文章
php實(shí)現(xiàn)Mongodb自定義方式生成自增ID的方法
這篇文章主要介紹了php實(shí)現(xiàn)Mongodb自定義方式生成自增ID的方法,實(shí)例分析了Mongodb自增字段的實(shí)現(xiàn)技巧與對(duì)應(yīng)php操作方法,需要的朋友可以參考下2015-03-03php數(shù)組函數(shù)序列之rsort() - 對(duì)數(shù)組的元素值進(jìn)行降序排序
rsort() 函數(shù)對(duì)數(shù)組的元素按照鍵值進(jìn)行逆向排序。與 arsort() 的功能基本相同。注釋?zhuān)涸摵瘮?shù)為 array 中的單元賦予新的鍵名。這將刪除原有的鍵名而不僅是重新排序。2011-11-11php讀取torrent種子文件內(nèi)容的方法(測(cè)試可用)
這篇文章主要介紹了php讀取torrent種子文件內(nèi)容的方法,可實(shí)現(xiàn)讀取并顯示torrent種子文件內(nèi)容的功能,簡(jiǎn)單實(shí)用,需要的朋友可以參考下2016-05-05PHP實(shí)現(xiàn)獲取第一個(gè)中文首字母并進(jìn)行排序的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)獲取第一個(gè)中文首字母并進(jìn)行排序的方法,涉及php數(shù)組遍歷、編碼轉(zhuǎn)換及數(shù)組排序相關(guān)操作技巧,需要的朋友可以參考下2017-05-05php dirname(__FILE__) 獲取當(dāng)前文件的絕對(duì)路徑
dirname(__FILE__) 取到的是當(dāng)前文件的絕對(duì)路徑,也就是說(shuō),比起相對(duì)路徑,查找速度是最快的。2011-06-06淺析memcache啟動(dòng)以及telnet命令詳解
本篇文章是對(duì)memcache啟動(dòng)以及telnet命令進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06php網(wǎng)站來(lái)路獲取代碼(針對(duì)搜索引擎)
獲取網(wǎng)站來(lái)路(針對(duì)搜索引擎)2010-06-06