内容:
一、 什么是DB类
二、 为什么要设计抽象的中间数据层
三、 DB的使用入门
四、 DB_Common 使用参考
五、 更进一步,创建你自己的中间数据库应用层
六、 DB的不足
七、参考资源
关于作者
相关内容:
1、用PEAR来写你的下一个php程序
2、常用模块
3、使用PHPDoc轻松建立你的PEAR文档
潘凡 (nightsailer@hotmail.com)
北京赛迪网信息技术有限公司
2001 年 8 月
对于PHP的应用程序来说,90%以上需要和数据库来打交道。那么,你是如何操纵数据库的?当你的后端数据库升级或变迁后,你的这些程序是否能够随之平滑地升级和挂接呢?如果你正在考虑这个问题,那么不妨和我来讨论一下,如何使用PEAR中的DB类来创建与数据库无关的数据库应用层。
一、 什么是DB类
我们首先简单地了解一下DB类。DB类是PEAR中进行数据操作的几个类的集合,它的主要目的是提供一个统一的,抽象的数据接口,这个接口与后端的数据库是无关的。因此,如果你的应用程序使用这个通用的接口来进行数据库的操作,那么就能够平滑地切换到不同的数据库下面,如MYSQL,SQL,SYBASE等等。实际上,DB类希望能够起到简单的类似ODBC或者是PERL中的DBI的作用。说到这里,不得不提一下PHP中的另一个优秀的库:ADODB。ADODB也和DB一样,提供了一个抽象的中间层,而且ADODB所支持的后端数据库要比DB多(至少目前如此),不过ADODB没有直接使用PEAR的一些特性,只是吸取了PEAR的许多思想,包括DB,因此二者的使用方法有许多相似的地方。我不想评论二者孰优孰劣,大家可以根据个人的喜好来使用。
二、 为什么要设计抽象的中间数据层
在详细讨论DB的使用之前,我们先讨论一下为什么要设计中间的数据层,因为这意味着你需要作出一些牺牲和让步,比如,你需要多写一些代码,有的局限于特定数据库的特性将无法直接使用。
我们回忆一下我们过去的做法,如何连接到MYSQL数据库?这的确是个小儿科的问题,下面的代码你一定很熟悉:
<?php
/**
* 连接到MYSQL数据库
*/
$host = "localhost";
$user = "root";
$passwd = "";
$persistent = 1;
if ($persisternt){
$conn = mysql_connect($host,$user,$passwd);
}else {
$conn = mysql_pconnect($host,$user,$passwd);
}
?>
好了,现在建立了数据库连接,我们可以使用它来进行数据库的操作,我们可能使用类似的代码:
<?php
function sql_exec($sql) {
global $db_Name;
$result = mysql_db_query($db_dbName,$sql);
if (!$result) {
echo mysql_errno(). ": ".mysql_error(). "<br>$sql<br>";
exit();
}
return $result;
}
$db_Name = "test";
$sql = "select * from users";
$result = sql_exec($sql);
while( $row = mysql_fetch_row($result) ){
echo "姓名:$row[0] 性别:$row[1] 年龄 $row[2]<br>";
}
mysql_free_result($result);
?>
看起来很不错,是吗?你可能在你的代码里使用很多类似的代码片段。但是,不要太高兴,问题来了。假如,突然,你的数据库需要从MYSQL迁移到别的数据库平台,比如ORACLE,SYBASE。迁移的原因很多,也许是你的老板突发奇想,认为这样能卖个好价钱,或者是你的数据猛增,导致MYSQL的性能下降,总之,迁移是事在必行了。你怎么做,你也许会想,呵呵,这简单,把相关的函数替换一下不就行了。
听起来简单,但是……首先,连接数据库的函数要改,需要把mysql_connect和mysql_pconnect替换成OCILogon和OCIPLogon。mysql_errno和mysql_error()当然不能使用,你需要从OCIError()返回的数组中提取响应的信息。
这还不是太糟,最糟的是相关的mysql_fetch_row,mysql_fetch_array等语句遍布于你的许多代码函数和过程中,你需要逐一查找,分析,然后重新替换或者编写相应的ORACLE的版本。如果,你的数据库操作是集中在一个某一个模块或类中,这项工作还可以接受,否则,等于你重新阅读和修改了绝大部分的代码。即使这个不幸的人不是你,那么他也会暗地里诅咒你的;=)
以上,我们回忆了我们以前的做法,以及可能带来的不幸。那么,如果使用DB类来做类似的操作,应该是什么样的呢?下面是相应的DB版本代码:
<?php
include_once "DB.php";
/*
* 连接到数据库
*/
$db_host = "localhost";
$db_user = "root";
$db_passwd = "";
$db_dbName = "test";
$PersistentConnection = 1 ;
$db_type ="mysql";
$db_proto ="";
$db = DB::connect("$db_type://$db_user@$db_passwd:$db_host/$db_dbName",$db_options);
if( DB::isError($db) ){
die "无法连接数据库,错误原因:".DB::errorMessage($db);
}
function sql_exec($sql) {
global $db;
$result =