+ -
当前位置:首页 → 问答吧 → 第17章 PHP数据库抽象层

第17章 PHP数据库抽象层

时间:2007-11-02

来源:互联网

本章着重讲述PHP数据库抽象层与数据库抽象类。
目前,在PHP的网站及众多书籍中,很少讲到数据库抽象层,有的PHP开发者虽然已做了几年开发工作,但似乎也没有意识到它的存在。

很多人并不理解数据抽象的重要性,也不了解mysql或mysqli扩展与PDO的区别,PDO与ADODB又有什么区别。
在本章中将讲述以下内容,通过学习,上面的问题都会迎刃而解。
Ø使用数据库抽象层的原因;
Ø数据库抽象层的发展;
Ø一些流行新抽象层的介绍;
ØPDO数据库抽象层开发技术;
ØADODB数据库抽象层开发技术。

17.1什么是数据库抽象层


使用数据库抽象层,意味着当从一个数据库系统向另一个数据库系统迁移时,几乎不用更改太多的程序代码,如将MS SQL Server迁移到MySQL。

首先,代码规划必须规范,即整个系统使用同一个数据对象实例,并且使用同一个较好的数据库抽象层。如果有一天用户要求将Oracle切换到MySQL,则只需要改变系统的配置文件即可。

在当今工业领域中,每个数据库开发商如微软、Oracle、MySQL,都有自己的一套SQL标准,它们声称是按照ANSI SQL92标准而增加自己的特性,以达到垄断或占领市场的目的。

优秀的数据库抽象层,会根据我们现在使用的数据库自动调整一些SQL性能。当没有使用数据库本身特定的特性时,就不必更改太多的数据库连接和数据库SQL查询。

使用数据库抽象层的其他好处是:其性质、概念简化了复杂的任务。因此,我们不必学习某个数据库系统的全新特性,而只用一个标准的抽象层的代码特性即可。

虽然这是一种理想化,但随着技术的发展,相信数据库抽象层会为我们做更多的事。

目前,使用PHP进行不同的数据库系统开发,这些系统很不相同,而许多数据库抽象层在PHP的层次有所不同,但彼此使用方法相当,它的发展无疑会提高开发效率。

请看图17-1,观察有数据抽象层和没有数据抽象层的区别。
数据库抽象层的主要性能指标是速度,由于数据库抽象层是额外的代码层,因为面向不同的架构与体系,因此有的效率较高,有的则相对比较慢些。

如Metabase是PHP中较慢的一个数据抽象层,它使用C语言编写,因为它的设计与可移植性最高,而PDO和ADODB是当今世界最快的数据库抽象类。


        (b)使用数据抽象层的PHP程序架构
图17-1
如果您非常关注系统的效率和性能,则可以按自己的基准,设置模拟环境,编写代码,测试每个数据库抽象层(类)的性能。


17.2常用的数据库抽象层


目前,有4种主流数据库抽象层:Metabase、PEAR:DB、PDO及ADODB。
从目前的应用来看,ADODB和PEAR:DB最受欢迎(因为PEAR是被捆绑在PHP目录中的,但PEAR:DB的效率问题一直引人诟病)。
从PHP 5开始出现的PDO及ADODB(其中包括PDO、MySQLi的底层实现)已经逐渐普及。
也有一些更新的抽象类值得一用,PEAR:MDB(现在的版本名称为PEAR:MDB2)已经将Metabase和PEAR:DB合并,并且效率较之从前有很大的提高。
我们先对现今常用的数据库抽象类的历史及它们的简要特点进行一一介绍。

17.2.1 PEAR:DB

PEAR:DB自2001年以来,存在于PEAR中,由于PEAR默认绑定在PHP目录中,基于这些原因,成为比较流行的数据库抽象层。PEAR:DB所支持的数据库系统包括:
ØFirebird
ØInterbase
ØInformix
ØmSQL
ØMS SQL Server
ØMySQL
ØOracle
ØODBC
ØPostgreSQL
ØSQLite
ØSybase
PEAR:DB的下载地址:http://pear.php.net/package/DB/download

17.2.2 ADODB

ADODB(Active Data Objects DataBase),起源于2000年,到目前为止仍然在增强与更新,发展至今仍然是一个热门的数据抽象层。
ADODB的开发初衷,源于很多从Microsoft ASP或ADO转过来的工程师,很多用法与MS ADO非常相像,目前使用ADODB的流行软件,例如egroupware、Mambo等均采用ADODB。
ADODB的数据库封包程序库提供了共通的应用程序界面来跟所有支持的数据库沟通,值得一提的是,它除了支持PHP,还支持Python语言。
ADODB提供很多实用的方法,使它超越了一个抽象层的功能,如具有表格化和数据库缓存等非常好的特性。ADODB支持的数据库系统包括:
ØAccess
ØADO
ØDB2
ØFirebird
ØFoxPro
ØFrontBase
ØInformix
ØInterbase
ØLDAP
ØMS SQL Server
ØMySQL
ØODBC
ØOracle
ØPostgreSQL
ØSAP DB
ØSQLite
ØSybase

另外,因为ADODB的逐渐发展,特性增强,使得本身体积过大,为此ADODB开发团队还提供了基本功能的ADO Lite。
有关ADODB的使用和开发方法,我们会在17.4节重点介绍。

17.2.3
Metabase

Metabase由Manuel Lemons开发。Metabase已被誉为慢抽象层,但是它支持PHP的全部版本,也是目前提供最大的可移植性设计的唯一抽象层。目前支持的数据库系统包括:
ØAccess
ØInformix
ØInterbase
ØmSQL
ØMS SQL Server
ØMySQL
ØODBC
ØOracle
ØPostgreSQL
ØSQLite
下载地址:http://www.phpclasses.org/browse/package/20.html#download。

17.2.4 MDB

SCMV-MDB的性能介于和融合PEAR:DB、Metabase数据库抽象层之间,它的初衷就是试图改善性能和最大可移植性。稳定版于2004年4月发布。
MDB目前支持的数据库系统包括:
ØFirebird
ØFrontbase
ØInterbase
ØMS SQL Server
ØMySQL
ØOracle
ØPostgreSQL
ØQuerysim
PEAR:MDB下载地址:http://pear.php.net/package/MDB/download

17.2.5 MDB2

PEAR:MDB2把Metabase/PEAR:DB合并,并在SCMV-MDB的基础上进一步巩固,以及去除不必要的冗余工作。另外,它还整合了与PDO的接口。
PEAR:MDB2目前支持的数据库系统包括:
ØFirebird
ØFrontbase
ØInterbase
ØMS SQL Server
ØMySQL
ØOracle
ØPostgreSQL
ØQuerysim
ØSQLite
PEAR:MDB2下载地址:http://pear.php.net/package/MDB/download

17.2.6 Creole

Creole是基于Java的JDBC技术,在某种程度上是PEAR:DB、PEAR: MDB2和ADODB的结合体。
Creole是PHP 5上较新的数据抽象层,与PHP 4不兼容。Creole提供充分的面向对象开发的API,以及PHP 5的异常处理机制。
Creole目前支持的数据库系统包括:
ØMySQL
ØMS SQL Server
ØOracle(in progress)
ØPostgreSQL
ØSQLite
Creole库的下载地址:http://creole.phpdb.org/wiki/index.php?node=2。

17.2.7 PDO

PDO数据抽象层是随着PHP 5.1推出的,PDO使用C语言编写,因为是与PHP同级的API,所以它的执行速度快。PDO目前支持的数据库系统包括:
ØFirebird
ØFreeTDS
ØInterbase
ØMySQL
ØMS SQL Server
ØODBC
ØOracle
ØPostgreSQL
ØSQLite
ØSybase
PDO必须运行在PHP 5.1及以上版本上。本章会重点讲述PDO的编写方法。

17.2.8 PHPLib

到目前为止,PHPLib已经使用了近6年,只是因为它曾经是非常受欢迎的数据库类,它在设计时并不是一个数据库抽象层,而只用于概括连接串、查询和处理错误和封装。
因为它小巧方便,加载速度快,现在使用这个类作为数据库层查询的PHP项目也为数不少。PHPLib的官方网站为:http://phplib.sf.net。
附件: 您所在的用户组无法下载或查看附件

作者: PHPChina   发布时间: 2007-11-01

刚才看了几章写的不错,明天到地下书城看一下能不能买到.

只买过一本59的PHP书

79*8=63 如果买的话这是我买的最贵的PHP书了.

不过还是支持!!!

作者: dx_andy   发布时间: 2007-11-01

17.5 PHPLib


PHPLib可能是伴随PHP一同成长最老的数据库抽象层(但和ADODB相比,它只算是一个MySQL抽象类库),当前最新版本为7.4a。我们只需要它的数据库访问功能,除了支持MySQL外,它也同时支持访问Oracle 8以上版本的数据库。
PHPLib访问SQL数据的类名为DB_Sql,包含在db_mysql.inc.php文件中。我们要使用的仅是它的数据库抽象类,直接用require()和include()包含进来就可以进行开发了。下面是开发实例,并且所用类库都是最新版本,这些都可以在光盘中找到。

17.5.1 使用PHPLib查询

首先定义一个配置文件config.inc.php,用于扩展PHPLib的MySQL类:DB_Sql。代码内容如下:
复制PHP内容到剪贴板
PHP代码:

<?php
/*** 系统路径,可根据需求更改路径 */
   define('ROOT', './');
   
/*** PHPLib library path */
   define('DB_HOST', 'localhost');
   define('DB_USER', 'root');
   define('DB_PASSWORD', 'root');
   define('DB_NAME', 'phpdev');
   require_once(ROOT."lib/db.inc.php");
   $db = new DbClass;

/*
    设置字符集,如utf-8和gbk、Latin1等,根据数据库的字符集而定,如果是Latin1,则可以不需要运行

*/
   $sql = "SET NAMES 'utf8'";
   $db->query($sql);

?>

上面代码引用的db.inc.php用于扩展DB_Sql类,主要是重新声明连接的数据库和账号,以及出错信息的处理和显示功能,如下所示。
复制PHP内容到剪贴板
PHP代码:

<?php
   require_once("db_mysql.inc.php");
   class DbClass extends DB_Sql{
   public $Host;
   public $Database;
   public $User;
   public $Password;
   function __constructor()
   {
      $this->Host = DB_HOST;
      $this->Database = DB_NAME;
      $this->User = DB_USER;
      $this->Password = DB_PASSWORD;
   }
  
   function halt($msg)
   {
      printf("</td></table><b>Database Error:</b> %s<br>\n", $msg);
      printf("<b>MySQL Error</b>: %s (%s)<br>\n",
      $this->Errno, $this->Error);
      printf("Please contact administrator and report the ");
      printf("exact error message.<br>\n");
      die("Session halted.");
   }
}
?>

我们还以symbols表为例,查询该表的数据,然后全部显示出来。
复制PHP内容到剪贴板
PHP代码:
<html> 
<head> 
<title>国家代表动物</title> 
</head> 
<body> 
<?php 
   require_once('lib/config.inc.php'); 
   $sql = "SELECT * from symbols"; 
   //也可以使用该方法执行INSERT、UPDATE、DELETE等SQL查询
   $db->query($sql); 
?>
<table cellpadding=10 border=1>
<tr>
<?php
   while($db->next_record()) { 
      $country = $db->f("country");
      $animal = $db->f("animal"); 
      $cname = $db->f("cname"); 
      echo "<tr>";
      echo("<td><b>国家:</b> </td><td>$country </td><td><b>代表动物:</b> </td><td>$animal ($cname) </td>\n"); 
      echo "</tr>";
   } 
?> 
</tr> 
</table>
</body> 
</html>
显示结果如下:


关于$db->next_record(),这是一个没有返回值的语句,它的功能是将当前表的指针向前移动并更新Record、Error、Row、Errno的方法。
while($db->next_record()) {

}
我们根据它的指针循环操作,直至到达尾记录,若条件不满足,则while退出循环。
$name = $db->f("name");
给$name变量分配的是数据字段name的值。

echo("<p><b>国家:</b> $country   <b>代表动物:</b> $animal ($cname)<br>\n");
echo("</p>\n\n");
打印出一行数据,也可不用变量赋值,而是直接引用方法返回的字段名即可,但是这种方法没有上面程序的可读性好。
复制PHP内容到剪贴板
PHP代码:
while($db->next_record()) { 
   echo("<p><b>国家:</b> ".$db->f("country")."   <b>代表动物:</b> " 
   .$db->f("animal")."(".$db-f("cname")."<br>\n"); 
   echo("</p>\n\n"); 
}

我们也可以开发一个函数,像ADODB或PDO那样,让抽出的记录生成一个二维关联数组。这样,PHPLib同样也可以与Smarty引擎协同工作,并且工作更方便,请看如下代码。
复制PHP内容到剪贴板
PHP代码:

<?php
   function GetAll($sql){
      global $db;
      //全局PHPlib $db的实例
      $db->query($sql);
      $Array = array();
      $j= 0;

      while($db->next_record()) {
         $Array[$j]= $db->Record;
         $j++;
      }

      return $Array;
}
?>

然后把该方法放在一个文件中,比如func.inc.php,同样保存在lib目录下。这样,我们再不用每次都重复使用while循环,直接调用该函数即可。
复制PHP内容到剪贴板
PHP代码:

<?php
   require_once('lib/config.inc.php');
   require_once('lib/func.inc.php');
   $sql = "SELECT * from symbols WHERE country='China'"; 
   $getAnimal = GetAll($sql);
   print_r($getAnimal);
?>

在浏览器上的显示结果如下:
Array
(
   [0] => Array
   (
      [0] => 2
      [id] => 2
      [1] => China
      [country] => China
      [2] => dragon
      [animal] => dragon
      [3] => 龙
      [cname] => 龙
   )
)

GetAll方法产生的$getAnimal关联数组和ADODB的是一样的,这样,我们可以让PHPLib和Smarty匹配,把该数组抛给模板显示即可。
虽然没有ADODB、PDO那么强大,但PHPLib小巧方便,对于系统负载相对较小。如果仍在旧版本下或虚拟主机环境下进行开发,使用它也是不错的选择。



17.6 小结

在本章中,我们一起了解了PDO及ADODB数据库类与抽象层在Web应用程序中的应用开发。其中包括记录集的概念(resultsets),如何连续获得表信息,如何使用PDO、ADODB进行优化查询,提高查询效率,以及结果缓存化的方法,如何输出HTML或其他格式文本的方法。
通过前面的介绍,相信您已经了解了数据库抽象层的特点和重要性:良好且丰富的功能和方法,方便使用,良好伸缩性与可移植性。
下一章,我们将要讨论PHP中热门且较实用的内容――页面模板化与Smarty技术。
附件: 您所在的用户组无法下载或查看附件

作者: PHPChina   发布时间: 2007-11-01

不错不错,看得出作者功底很扎实!

作者: chenz1117   发布时间: 2007-11-02

学习了!

作者: renwl   发布时间: 2007-11-02

好强的书啊,感觉很全面,很实用啊,不过如果新人学这么多东西是不是会很累很累,难道就不能快速上手然后再逐步提高,提点小意思,觉得能不能把一本书分块,分成初中高三级,让人可以真正分阶段分目标学习,也要相互联系,最后能成一套系统。

作者: jfcat   发布时间: 2007-11-02

提点小意见
打错了啊

还是发个电子版,由于文件太大无法上传,只能发WORD版的
将就点看吧
附件: 您所在的用户组无法下载或查看附件

作者: jfcat   发布时间: 2007-11-02

引用:
原帖由 jfcat 于 2007-11-2 20:44 发表
提点小意见
打错了啊

还是发个电子版,由于文件太大无法上传,只能发WORD版的
将就点看吧
兄弟你是好人,我跟踪你三个回帖了,昨天看这个主题你没回帖,我就等今天再来看,终于等到你的回帖了,
我是不是有懒人嫌疑啊

作者: jyb21   发布时间: 2007-11-04

第八章有个错误,看来这书还是有错误的,不过作者还是很厉害的,我也就不为难作者了,还是支持他一下,毕竟写个这么多页的书不容易,而且还是写的这么详细,把自己这么多年的开发心得都贡献出来了,更是难得。不得不支持

作者: jyb21   发布时间: 2007-11-04

有错误是正常的,我们尽量把错误避免和最小化。

原则上的大问题,应该是没有。

作者: phpcast   发布时间: 2007-11-04

引用:
原帖由 phpcast 于 2007-11-4 22:21 发表
有错误是正常的,我们尽量把错误避免和最小化。

原则上的大问题,应该是没有。
我现在把你已发布的章节和PHP圣经第三版在作比较,我感觉你的就是中国版的圣经,我再仔细看看,如果相似内容不多的话,我还打算买你这本。
因为里面有你的很多经验可以参考,我可以少走很多弯路了。

作者: jyb21   发布时间: 2007-11-04

请仔细甄别,呵呵

作者: phpcast   发布时间: 2007-11-04

引用:
原帖由 jyb21 于 2007-11-4 22:12 发表

兄弟你是好人,我跟踪你三个回帖了,昨天看这个主题你没回帖,我就等今天再来看,终于等到你的回帖了,
我是不是有懒人嫌疑啊
给大家提供点方便,我只能仅点微薄之力,希望对大家学习有帮助。一起努力吧

同时还要感谢作者花心血写这么一本书,让大家能少走弯路。一本好书犹如一位好老师,现在很多的资料都是国外的,而且大多是一年前的了,很多东西都发生了很大的变化,并且由于文化的差异性,他们的语言、例子、图本章节的排版等,有时候对我们理解问题带来不好的效果,所以就有了很多批评译本,以及译者的言行,在此我不对此多加评论,只希望多一些像《PHP5与MYSQL5 web开发技术详解》这样的好书。写作都会出些小问题,特别是技术书籍,技术变化总是很快的,涉及面也广泛所以也容易出错,特别希望能将错误总结出来,学习知识是来解决问题的,对书中问题的解决一自然是一种学习,对自己提高的每一次帮助我们都要抓住,那怕是很小的问题,说不准你就会遇到。其它我也没多少说的,编程就要多练多总结,光看不够还要多做,做多了还要多想想,找出更好的方法,让做事情更容易,更能节省我们自己的时间创造更大的个人价值。
    这里不是帮作者做宣传(肯定作者也不会要我这差的宣传员),只是对大概整理这几章之后的总结。仅此!!

作者: jfcat   发布时间: 2007-11-05

很好的东西...

作者: nantangcun   发布时间: 2007-11-15

热门下载

更多