日期:2014-05-16  浏览次数:20549 次

PHP数据库连接类--DB类

对于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 = $db->query($sql);
if (DB::isError($result)){
echo "发生数据库错误:".DB::errorMessage($result);
exit();
}
return $result;
}
/////////////////////////////////////////////
$sql = "select * from users";
$result = sql_exec($sql);
while( $row = $result->fetchRow() ){
echo "姓名:$row[0] 性别:$row[1] 年龄 $row[2]<br>";
}
?>


除了连接数据库部分,其他的看起来只是有一些微小的变化,出错处理使用的是PEAR类似的方式(isError),实际上也是从PEAR继承来的。同样的情况,如果你要把数据库从mysql迁移到别的形式,这次假如说是PostegreSQL,一个LINUX中很优秀的数据库,你所做的只是改变一行代码:

$db_type ="mysql";
变成:
$db_type ="pgsql";


其他的,不用变动。怎么样,升级的感觉是不是很清爽呢,你可以用剩下的时间好好研读其余的代码,或者和我继续往下讨论DB的使用方法。




回页首




DB的使用入门

DB类由3部分组成:

DB.php 这是前端接口,在DB类里提供了许多"静态"的公用方法,我们一般只需要INCLUDE_ONCE这个文件就可以了。
DB/common.php 这是后端数据库的通用抽象类,不同的数据库的后端类需要继承并实现这个类中定义的公用方法和属性,如果你的数据库不被支持,你可以自己编写一个支持类,这样,你的应用程序就可以迁移过来了。
DB/storage.php 这是一个辅助的工具,它可以把SQL查询做为对象返回,同时能够维护这些对象,在对象改变的时候,相应地更新数据库。
DB/ifx.php

mssql.php Ms SQL Server支持类
oci8.php Orcale 8i支持类
pgsql.php PostegreSQL支持类
sybase.php Sybase支持类
ibase.php ibase支持类
msql.php mSQ