說(shuō)起數(shù)據(jù)抽象層,大家可能首先想起的就是ADODB。這里要為大家介紹的是一個(gè)全新的數(shù)據(jù)抽象層:Creole。說(shuō)它新,是因?yàn)樗怯肞HP5寫的,是一個(gè)基于真正意義的OO的層;它的API接口以JDBC為基礎(chǔ),熟悉JDBC的朋友用起來(lái)應(yīng)該會(huì)很親切;它現(xiàn)在支持的數(shù)據(jù)庫(kù)有MySQL, MS SQL Server, PostgreSQL, SQLite。Oracle的driver正在開(kāi)發(fā)中,當(dāng)然,你也可以為自己要使用的數(shù)據(jù)庫(kù)寫Driver。
安裝
下面我們就來(lái)看看在Windows+Apache+PHP5上Creole的安裝和初步使用。首先你要安裝好PEAR,如果你還沒(méi)有安裝好,可以雙擊php目錄下的go-pear.bat文件,然后這個(gè)程序會(huì)引導(dǎo)你進(jìn)行安裝。關(guān)于PEAR的安裝不是本文的內(nèi)容,請(qǐng)自行查閱相關(guān)資料。當(dāng)你安裝好PEAR后,我們就要利用它的install功能了。
首先進(jìn)入命令行方式,Cd到你安裝php的目錄下。然后在命令行中鍵入下邊命令,這樣PEAR會(huì)自動(dòng)幫我們下載并安裝好Creole包。
pear install http://creole.phpdb.org/pear/creole-current.tgz
如果你鍵入的命令正確的話,應(yīng)該看到下邊的安裝提示。
500) this.width=500" vspace=10 border=0>
這樣我們就已經(jīng)成功安裝好了Creole,不過(guò)為了能使用它我們還得再安裝一個(gè)jargon包,這個(gè)包封裝了數(shù)據(jù)表和字段層次的一些信息。安裝的方法和上邊一樣,鍵入如下命令就可以了:
pear install http://creole.phpdb.org/pear/jargon-current.tgz
配置
下面我們就可以使用Creole了。在web可以訪問(wèn)的目錄下建立一個(gè)PHP文件,我們先來(lái)嘗試包含Creole類,這是每一個(gè)要使用Creole的程序都要做的事。我們加入下邊的代碼:
require_once 'creole/Creole.php';
然后在瀏覽器中訪問(wèn)這個(gè)頁(yè)面,結(jié)果出現(xiàn)了下邊的錯(cuò)誤:
Warning: main(/creole/Creole.php) [function.main]: failed to open stream: No such file or directory in c:/program files/EasyPHP5/home/dev/test.php on line 2
Fatal error: main() [function.require]: Failed opening required '/creole/Creole.php' (include_path='.;C:/php5/pear') in c:/program files/EasyPHP5/home/dev/test.php on line 2
這是因?yàn)槲覀儧](méi)有設(shè)置好php.ini來(lái)包含PEAR庫(kù)的路徑,所以php.exe找不到文件,只好報(bào)錯(cuò)了。現(xiàn)在我們把PEAR庫(kù)的地址添加到php.ini中。在php.ini中找到這段:
;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;
; UNIX: "/path1:/path2"
;include_path = ".:/php/includes"
;
; Windows: "path1;path2"
;include_path = ".;c:/php/includes"
將最后一行改成:
include_path = ".;C:/Program Files/EasyPHP5/php/PEAR"
其中C:/Program Files/EasyPHP5/php/PEAR是PEAR在你機(jī)器上的絕對(duì)路徑。注意要去掉行首的分號(hào)。然后重啟Apache。再訪問(wèn)看看,好了。:)
試用
現(xiàn)在開(kāi)始我們就可以在程序中使用Creole了。下邊我們將連接數(shù)據(jù)庫(kù),并從中取出user表的全部用戶。下邊是完整的代碼:
<?php
require_once 'creole/Creole.php';
$dsn = "mysql://root@localhost/r4";
$conn = Creole::getConnection($dsn);
$rs = $conn->executeQuery("SELECT * FROM user");
while($rs->next())
{
echo $rs->getString("login_name") . " (" . $rs->getInt("id") . ")";
}
?>
這里講解下上邊代碼的含義。第一行載入了Creole類,第二行定義了一個(gè)用于連接數(shù)據(jù)庫(kù)的字符串,格式是“數(shù)據(jù)庫(kù)類型名://用戶名:密碼@HOST/數(shù)據(jù)庫(kù)名”。第三行創(chuàng)建了一個(gè)連接對(duì)象,第四行利用這個(gè)對(duì)象執(zhí)行了一句SQL,并返回一個(gè)結(jié)果集。第五到八行遍歷了這個(gè)結(jié)果集并輸出數(shù)據(jù)。
析構(gòu)
怎么樣,看起來(lái)不錯(cuò)吧,如果你感興趣可以按照Creole站上的Guide一步一步做下去。不過(guò)我們就要做別的事情了:P 前邊說(shuō)過(guò)了,Creole更多的注重于OO,同時(shí)又帶有很強(qiáng)的Java風(fēng)格,因此對(duì)于我們學(xué)習(xí)使用PHP5來(lái)設(shè)計(jì)OO方式的程序是很好的范例。下邊我們就來(lái)看看它的架構(gòu)。首先要了解的是它的目錄結(jié)構(gòu),在Windows命令行方式鍵入tree,就可以打印出一個(gè)目錄的結(jié)構(gòu)(一個(gè)有用的小技巧哦),下邊是由此得到的Creole目錄結(jié)構(gòu),目錄后邊加上了簡(jiǎn)要的說(shuō)明。
我們以Statement為例,看看Creole是怎么組織的。首先在根目錄下的Statement.php中定義了Statement接口,這個(gè)接口規(guī)定了Statement必須實(shí)現(xiàn)的一些方法。然后,在/common目錄下的StatementCommon.php中定義了名為StatementCommon的抽象類,在這個(gè)類中,包含了Statement.php中定義的接口的實(shí)現(xiàn)代碼,但是并沒(méi)有定義為實(shí)現(xiàn)Statement接口。
Root // Creole的根目錄
├─common // 存放了Creole的抽象類
├─drivers
│ ├─mssql
│ │ └─metadata // mssql實(shí)現(xiàn)
│ ├─mysql
│ │ └─metadata // mysql實(shí)現(xiàn)
│ ├─pgsql
│ │ └─metadata
│ └─sqlite
│ └─metadata
├─metadata // 數(shù)據(jù)表原始信息類
└─util
└─sql
而在/drivers/mysql/目錄下的MysqlStatement則繼承了StatementCommon和實(shí)現(xiàn)Statement方法。這樣MysqlStatement可以共享到StatementCommon中的方法,需要定制時(shí)可以重載StatementCommon的方法;同時(shí),MysqlStatement又受到Statement接口的約束。
下一頁(yè)的圖表示了Statement,StatementCommon和MysqlStatement之間的關(guān)系。正是這樣的結(jié)構(gòu),使定義和實(shí)現(xiàn)得到了有效的分離。Creole中大量采用了這樣的結(jié)構(gòu),在我們編寫自己的Driver時(shí)非常方便。如果要添加一個(gè)TextStatement,可以自己實(shí)現(xiàn)一個(gè)class,只要這個(gè)class實(shí)現(xiàn)了Statement接口就可以了。而Driver正是由這樣的一組class組成的。
500) this.width=500" vspace=10 border=0>
參考
我們對(duì)Creole的介紹到這里就告一個(gè)段落了,而對(duì)你來(lái)說(shuō),一切才剛剛開(kāi)始。下邊是從兩個(gè)常用類的接口程序內(nèi)中整理出來(lái)的方法,希望能對(duì)你有所幫助。
Statement
public function setLimit($v);
public function getLimit();
public function setOffset($v);
public function getOffset();
public function close();
public function execute($sql, $fetchmode = null);
public function getResultSet();
public function executeQuery($sql, $fetchmode = null);
public function executeUpdate($sql);
public function getMoreResults();
public function getConnection();
ResultSet
public function getResource();
public function setFetchmode($mode);
public function getFetchmode();
public function isIgnoreAssocCase();
public function next();
public function previous();
public function relative($offset);
public function absolute($pos);
public function seek($rownum);
public function first();
public function last();
public function beforeFirst();
public function afterLast();
public function isAfterLast();
public function isBeforeFirst();
public function getCursorPos();
public function getRow();
public function getRecordCount();
public function close();
public function get($column);
public function getArray($column);
public function getBoolean($column);
public function getBlob($column);
public function getClob($column);
public function getDate($column, $format = '%x');
public function getFloat($column);
public function getInt($column);
public function getString($column);
public function getTime($column, $format = '%X');
public function getTimestamp($column, $format = 'Y-m-d H:i:s');
作者簡(jiǎn)介
Easy Chen , 04年畢業(yè)于石油大學(xué)(北京) 計(jì)算機(jī)系,ReleaseEasy/ Rticle 作者。喜好網(wǎng)絡(luò)技術(shù)寫作,《PHP&MORE》編輯,聯(lián)系信箱:EasyChen at Gmail.com