关于 PHP 的数据库 API 对于不同的数据库有不同的函数,一直以来就有人尝试使用 PHP 的面向对象的功能进行一些封装。其中有比较著名的ADODB,PHPLIB。后来举世瞩目的 PEAR 项目中的 PEAR DB 更是其中的佼佼者。这些用面向对象对数据库 API 进行的封装的包一般称为数据库抽象层。
本文介绍的是 PEAR 中对 PEAR DB 进行融合 Metabase 库的一些优秀功能之后产生的注重效率,而且简单易用,功能非常强大的 MDB 的一个非常好的介绍。作者就是 MDB 的主创人员。
想获得我最近关注的 PHP/PEAR 的最新原创和译文,请访问我的主页
Write once - run anywhere
一次编写??随处运行
PEAR MDB Database Abstraction Layer
PEAR MDB 数据库抽象层
作者:Lukas Smith
译者:taowen
While this is a Java marketing phrase it is also a key feature of PHP. Many business models depend on operation system independence to ensure that products can be sold to a wide range of customers. So why lock yourself in with a specific database vendor? Database abstraction layers allow you to develop your application independent of a database. But often they eat more performance than you are willing to give or they do not abstract enough to eliminate all database specific code.
这是Java的一句行销口号,但是它同时也是PHP的关键特性之一。许多商业模型依赖于操作系统无关性来保证产品能够销售给广泛的客户群体。因而,为什么要把你自己绑在某种数据库厂商的身上呢?数据库抽象层使得你能够与数据库独立的开发你的应用程序。但是,通常情况下它们对性能的影响超过了你所希望的,要么他们并不足够抽象以消除所有和特定数据库相关的代码。
What will this article teach me?
这篇文章将教给我什么?
This article will give a good introduction to the database abstraction package PEAR MDB. The focus will be explaining the more advanced features of MDB like data type abstraction and the XML based schema management that go beyond what other similar packages offer. A basic level of understanding of PHP and SQL is recommended.
这篇文章将对数据库抽象包 PEAR MDB 有一个很好的介绍。文章的焦点将是对 MDB 超越类似包所提供的更先进的特性,例如数据类型抽象和基于 XML 的 schema 管理。对 PHP 和 SQL 的基本理解是推荐的。
Why another database class?
为什么另外再要一个数据库类?
Often, web projects are added to existing IT infrastructures, where the client already made a choice of what RDBMS (relational database management system) to work with. Even if that is not the case different budgets might affect what database you chose for deployment. Finally, you as the developer simply might prefer not to lock yourself in with a specific vendor. So far this meant to keep multiple versions for each supported database or giving up more performance and ease of use than necessary: Enter PEAR MDB.
通常, web 工程在客户已经确定了要使用那种 RDBMS (关系型数据库管理系统)之后被添加给已经存在的 IT 基础结构。即使那并不是因为不同的预算可能影响的你选择何种数据用于部署的情况。最终,你作为开发者可能简单的偏好于不把自己绑在某个厂商身上。自此,意味着给每个支持的数据保持版本或者牺牲更多性能但是获得多于必须的易用性:走入 PEAR MDB 吧。
MDB is a database abstraction layer that aims to make writing RDBMS independent PHP application development a straightforward process. Most other so called database abstraction layers for PHP only provide a common API for all supported databases and only very limited abstraction (mostly only for sequences). MDB on the other hand can be used to abstract all data being send and received from the database. Even database schemas can be defined in a RDBMS independent format. But it does this while retaining a high level of performance and ease of use. This was achieved by closely examining two popular database abstraction layers, PEAR DB and Metabase, and merging them. But during the merging the opportunity was also used to clean up their merged APIs as well as any performance hindering design patterns.
MDB 是着眼于使得编写 RDBMS 无关的 PHP 程序成为简单的过程的数据库抽象层。大部分其他的 PHP 的所谓数据库抽象层紧紧给所有支持的数据库提供了一个公用 API 以及非常有限的抽象(大部分只是针对序列的)。MDB 另一方面能够用来抽象所有数据库发送和接收的数据。甚至数据库 schema 都能被定义为 RDBMS 无关的格式。但是它提供这些功能的同时仍然保持了很高的性能以及简单易用。这是通过深入观察两个流行的数据库抽象层,PEAR DB 和 Metabase, 之后并且对它们进行了融合后获得的。而且在融合过程中,趁着这个机会清理了它们融合后的 API 以及任何影响性能的设计。
How did MDB come to be?
MDB 是怎样出现的?
Back in fall 2001, I was looking for a database abstraction package that would make my companies application framework RDBMS independent. The goal was to reduce database specific code to zero. The only package I found that offered such features was Metabase. But Metabase had a somewhat uncomfortable API that was partly a result of the compatibility to PHP3. This also made Metabase slower than it needed to be for our purposes, since we did not need PHP3 compatibility. Nonetheless, we decided that Metabase is our only option. But even after adding a performance enhancing patch to Metabase we felt that we were giving up too much performance. We met with the author of Metabase at the International PHP Conference 2001 and we talked about the benefits of having something like Metabase as part of the PEAR project. Shortly afterwards a discussion began once more in the PEAR mailing list about the potential benefits of a merge of PEAR DB and Metabase. After much discussion at my company we decided to take up this task. After several months of hard work we now have the first stable release of MDB.
早在 2001 年的秋天,我就在寻找一种可能能够让我公司的程序框架与 RDBMS 独立的数据库抽象包。这个目标是把特定数据库相关的代码数量减少到零。我发现提供这样的功能的唯一的一个包是 Metabase。但是 Metabase有一些部分是因为为了和 PHP3 兼容的让人不舒服的 API。尽管如此,我们决定 Metabase 是我们唯一的选择。但是即使是在给 Metabase 增加了一个性能改进的补丁之后,我们仍然感到我们放弃了太多的性能。我们在 2001 年的 PHP 国际会议上碰到了 Metabase 的作者,并且我们谈论了让像 Metabase 这样的东西成为 PEAR 工程一部分的好处。后来不久,在 PEAR 邮件列表上就 PEAR DB 和 Metabase 融合的可能的好处又开始了一场讨论。在我们公司进行了许多讨论之后,我们决定承担这个任务。数个月的艰辛工作之后,我们现在有了 MDB 的第一个稳定的 release。
What does MDB do for you?
MDB 给你提供了什么?
MDB combines most of the features of PEAR DB and Metabase. Actually, the only feature that is missing is PEAR DB's feature of returning an object as a result set. This feature was dropped because the feature's usage never became abundant but the performance penalty was quite apparent. A lot of development time was spend on making the API as intuitive as possible as well. Finally, MDB provides this functionality at a very high level of performance that is at least as fast as PEAR DB and much faster than Metabase. Here is the list of the most important features:
MDB 结合了 PEAR DB 和 Metabase 的大部分特性。实际上,PEAR DB 的特性中唯一不再存在的是作为结果集返回一个对象。我们放弃了这个特性是因为这个特性不常用而且对于性能的损失是非常明显的。许多开发上的时间用在了使得 API 尽可能的好用。最终,MDB 非常高地提供了这些功能至少和 PEAR DB 一样快而且比 Metabase 快很多。这些最重要地特性的列表:
OO-style API
prepared queries emulation
full data type abstraction for all data passed to and from the database (including LOB support)
transaction support
database/table/index/sequence creation/dropping/altering
RDBMS independent database schema management
Integrated into the PEAR framework (PEAR Installer, PEAR error handling etc.)
OO 风格的 API
预准备的查询模拟
给所有传递进来以及从数据库中取出的数据的完全的数据类型抽象(包括 LOB 支持)
事务支持
数据库/表/索引/序列创建/抛弃/改变
RDBMS 无关的数据库 schema 管理
继承进 PEAR 框架(PEAR 安装程序,PEAR 错误处理等)
So how does it work?
那么它如何使用呢?
MDB provides some very advanced abstraction features. It is important to keep in mind that these features are optional. But using them is critical in writing RDBMS independent PHP applications. An example of how the basics of MDB work can be found under Links & Literature at the end of the article. As stated earlier, the focus of the article is to introduce the features that set MDB apart from other database abstraction layers for PHP. You can find example scripts for all code examples found in this article on the CD that is packaged with this issue.
MDB 提供了一些非常先进的抽象特性。记住这些特性只是供选择的是很重要的。但是在编写 RDBMS 无关的 PHP 程序时使用它们是非常重要的。一个展示使用 MDB 是多么简单的例子在文章的结尾的 "链接和文献" 部分。如前面所说,文章的焦点是介绍使得 MDB 与其他 PHP 数据库抽象层不同的那些特性。你可以在随本期文章一同包装的 CD 中找到所有这些例子脚本的代码。
But first we will need to get MDB installed. This is actually quite easy using the PEAR installer. I cannot cover the entire PEAR Installer within this article but I hear the next issue will talk about great details about all the ins and outs of the PEAR framework. There is work going on to make the Installer work on Windows but the support is still a bit flaky. For *nix systems you will need a CGI version of PHP installed on your system and simply run the following command:
但是,首先我们需要把 MDB 安装上去。使用 PEAR 安装程序这其实非常容易。我不能在这篇文章中完整的讲述 PEAR 安装程序但是我听说下一期将非常详细的讨论 PEAR 框架的里里外外。让安装程序运行于 Windows 的工作在进行当作但是支持仍然有一点古怪。对于 *nix 系统你需要 PHP 的 CGI 版本安装在了你的系统并且简单地运行下面地命令:
lynx -source go-pear.org|php
After completing the installation process you simply need to type one more command and you are all set.
在安装完成之后你只需要再输入一行命令那么就全部搞定了。
pear install MDB
If the above does not work for you there is always the option of getting the package directly from the PEAR MDB homepage. The URL is listed at the bottom of the article.
如果前面的过程对你来说不管用,总是有从 PEAR MDB 主页中直接获得包的选项。URL 列于文章的最后。
Making use of data type abstraction
利用数据类型抽象
Since most databases tend to have some specialities or quirks it is important for MDB to hide these differences from the developer. MDB achieves this by defining its own internal data types: text, boolean, integer, decimal, float, date, time, time stamp, large objects (files). All data that is passed to and from the database may be converted from MDB's internal format to the databases internal format. The accompanying example scripts to this section can be found in the datatype directory. Let us look at the following query:
因为大部分数据库倾向于有一些个性或者怪癖,对于MDB来说把这些不同之处给开发者隐藏起来非常重要。MDB 通过定义自己的内部数据类型来达到这点:text,boolean,integer,decimal,float,date,time,time stamp,large objects(文件)。所有传递给数据库和从数据库获取的数据都能转换成 MDB 的内部格式或者从数据库的内部格式转化回来。本节相关的例子脚本能够再 datatype 目录中找到。让我们看看下面的查询:
$session = '098f6bcd4621d373cade4e832627b4f6';
// set time out to 30 minutes
$timeout = time()+60*30;
// SELECT query showing how the datatype conversion works
$query = 'SELECT createtime, user_id FROM sessions';
$query .= ' WHERE session = '.$session;
$query .= ' AND lastaccess < '.$timeout;
This query will most likely fail if it were send to a database. The reason being that the value stored in $name would need to be converted to the correct string format. This would mean the contents of $name would have to have special characters escaped and quotes placed around. PEAR DB provides the method DB:.quote() for this. In MDB the method is called MDB::getTextValue(). The difference is that MDB offers such a method for every data type listed above. So we can also convert $timeout to the correct format.
这个查询如果发送给数据