php adodb介绍


Posted in PHP onMarch 19, 2009

虽然 PHP 是建构 Web 系统强有力的工具,但是 PHP 存取数据库的功能,一直未能标准化,每一种数据库,都使用另一种不同且不兼容的应用程序接口(API)。为了填补这个缺憾,因此才有 ADODB 的出现。一旦存取数据库的接口予以标准化,就能隐藏各种数据库的差异,若欲转换至其它不同的数据库,将变得十分容易。

目前 ADODB最新版本是V4.62,支持的数据库种类非常地多,例如:MySQL, PostgreSQL, Interbase, Informix, Oracle, MS SQL 7, Foxpro, Access, ADO, Sybase, DB2 以及一般的 ODBC (其中 PostgreSQL、Informix、Sybase 的driver 是由自由软件社群发展之后贡献出来的)。

使用 ADODB 最大的优点之一是:不管后端数据库如何,存取数据库的方式都是一致的,开发设计人员不必为了某一套数据库,而必须再学习另一套不同的存取方法,这大大减轻开发人员的知识负担,过去的知识往后仍可继续使用,转移数据库平台时,程序代码也不必做太大的更动。

其实 ADODB 这样的发展理念,并不是首创的,DBI 比 ADODB 出现得更早,它提供 Perl 存取数据库时,使用一致的 API 呼叫接口。相信用过 Perl + DBI 的朋友,再来用 ADODB 时,会有一种似曾相识的感觉。

另外,ADODB 对用过 ASP 的人而言,应该不陌生,这类朋友对 ADODB 应该很容易接受。

Adodb官方:http://adodb.sourceforge.net/
PHP可以用最少的精力以及最多的乐趣来建立动态的网站,要建立动态网站我们需要使用数据库来撷取登入账号信息、发布动态新闻、储存讨论区的文章。 就以使用最通用的 MySQL 数据来说,你们公司已经完成了如此神奇的工作,让你们的网站比你们所能想象的还要出名。接着你们也发现MySQL无法应付实际的工作量了,是该更换数据库 系统的时候了。
不幸地,在PHP中所有数据库的存取都有些细微的不同。与MySQL连结你要使用 mysql_connect(),当你决定升级到 Oracle 或 Microsoft SQL Server 时,你必须分别改用 ocilogon() 或 mssql_connect()。更糟糕的是不同连结所使用的参数也都不一样,有的数据库说 po-tato(马铃薯的发音),别的数据库又说 pota-to(马铃薯的另一个发音),喔…..天啊。
我们不要放弃
当你需要确保你程序的可移植性的时候,一个叫做 ADODB 的数据库封包链接库已经出现了。它提供了共通的应用程序接口来跟所有支持的数据库沟通,因此你无须放弃!
ADODB是Active Data Object DataBase的缩写(很抱歉!玩计算机的有时候不是很有原创性)。ADODB目前支持MySQL、PostgreSQL、Oracle、 Interbase、Microsoft SQL Server、Access、FoxPro、Sybase、ODBC及ADO,你可以从 http://php.weblogs.com/adodb下载 ADODB。
MySQL的例子
PHP中最通用的数据库是MySQL,所以我想你会喜欢下面的程序代码,它连结到 localhost 的 MySQL 服务器,数据库名称是 mydab,并且执行一个 SQL 的 select 指令查询,查询结果会一列列地印出来。
$db = mysql_connect("localhost", "root", "password");
mysql_select_db("mydb",$db);
$result = mysql_query("SELECT * FROM employees",$db);
if ($result === false) die("failed");
while ($fields = mysql_fetch_row($result)) {
for ($i=0, $max=sizeof($fields); $i < $max; $i++) {
print $fields[$i].' ';
}
print "<br>n";
}
上列的程序代码用颜色标出分段,第一段是连结的部分,第二段是执行SQL指令,最后一段则是显示字段,while循环扫描结果的每一列,而for循环扫描到每列的字段。
接下来是以ADODB的程序代码得到同样的结果:
include("adodb.inc.php");
$db = NewADOConnection('mysql');
$db->Connect("localhost", "root", "password", "mydb");
$result = $db->Execute("SELECT * FROM employees");
if ($result === false) die("failed");
while (!$result->EOF) {
for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
print $result->fields[$i].' ';
$result->MoveNext();
print "<br>n";
}
现在改成指向Oracle数据库,程序代码只要修改第二行成为 NewADOConnection('oracle'),让我们看一下完整的程序代码...
与数据库连结
include("adodb.inc.php");
$db = NewADOConnection('mysql');
$db->Connect("localhost", "root", "password", "mydb");
连结的程序代码比起原来MySQL的程序代码有老练一些,因为我们正是需要更老练些。在ADODB我们使用对象导向的方法来管理多样数据库的复杂 性,我们用不同类(class)来控制不同数据库。假如你不熟悉对象导向程序设计,别担心!所有的复杂事情都隐藏在 NewADOConnection() 函数之后。
为了节省内存,我们只加载与你所连结数据库相关的PHP程序代码,我们通过调用NewADOConnection(databasedriver) 来完成这件事,合法的数据库驱动程序包含 mysql,mssql,oracle,oci8,postgres,sybase,vfp,access,ibase 以及许多其它的驱动程序。
接着我们通过调用 NewADOConnection() 来从连结类别产生一个新的对象实体,最后我们使用 $db->Connect() 来连结数据库。
执行SQL指令
$result = $db->Execute("SELECT * FROM employees");
if ($result === false) die("failed");
直接传送SQL指令到服务器,当成功执行之后,Execute()将传回一个recordset对象,你可以如同上面所列来检查$result。
一个初学者容易混淆的议题是,在ADODB有两种类型的对象,连结对象以及recordset对象,我们何时用这些对象呢?
连结对象($db)是负责连结数据库,格式化你的SQL查询。而recordset对象($result)则是负责撷取结果并将响应数据规格化成文字或数组。
唯一我需要增加的事情是,ADODB提供许多有用的函数来让INSERT及UPDATE指令更容易些,这点我们在进阶的章节会提到。
撷取资料
while (!$result->EOF) {
for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
print $result->fields[$i].' ';
$result->MoveNext();
print "<br>n";
}
前面取得数据的范例很像从档案读数据,在每一行我们首先检查是否到了档案的结尾(EOF),若还没到结尾,循环扫过每列中的字段,然后移到下一行(MoveNext)接着重复同样的事情。
$result->fields[]数组是由PHP数据库延伸系统所产生的,有些数据库延伸系统并不会以字段名称建立该数组的索引,要强迫以名称排序索引该数组,使用$ADODB_FETCH_MODE的通用变量。
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs1 = $db->Execute('select * from table');
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); // shows array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); // shows array(['col1']=>'v0',['col2'] =>'v1')
如同你所见的上面例子,两个recordset储存并使用不同的取用模式,当recordset由Execute()产生后再设定$ADODB_FETCH_MODE。
ADOConnection
连结到数据库的对象,执行SQL指令并且有一组工具函数来标准格式化SQL指令,比如关联与日期格式等指令。
其它有用的函数
$recordset->Move($pos)卷动目前的数据列,ADODB支持整个数据库往前卷动,有一些数据库并不支持往后的卷动,这倒不会是个问题,因为你能够用暂存纪录到快取来仿真往后卷动。
$recordset->RecordCount()传回SQL指令存取到的纪录笔数,有些数据库会因为不支持而传回-1。
$recordset->GetArray()以数组的方式传回结果。
rs2html($recordset)函数将传进的recordset转为HTML的表格格式。下例中以粗体字显示相关用法:
include('adodb.inc.php');
include('tohtml.inc.php'); /* includes the rs2html function */
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
$rs = $conn->Execute('select * from table');
rs2html($rs); /* recordset to html table */
还有许多其它有用的函数列示在文件之中,可从下列网址查得 http://php.weblogs.com/adodb_manual
进阶题材
新增及更新
假设你要新增下列数据到数据库中。
ID = 3
TheDate=mktime(0,0,0,8,31,2001) /* 31st August 2001 */
Note= sugar why don't we call it off
当你改用别的数据库,可能就没办法新增数据。
第一个问题是,每一个数据库各自有不同的内定日期格式,MySQL使用 YYYY-MM-DD 格式,而其它数据库则有不同的内定格式,ADODB提供DBDate()函数来转换不同数据库之间的日期内定格式。
次一个问题是单引号(don't)的表示法,在MySQL可以直接使用单引号(don't),但在其它数据库如Sybase、Access、 Microsoft SQL Server,则用两个单引号表示(don''t),qstr()函数可以解决此问题。
我们如何使用这些函数?就像这样:
$sql = "INSERT INTO table (id, thedate,note) values ("
. $ID . ','
. $db->DBDate($TheDate) .','
. $db->qstr($Note).")";
$db->Execute($sql);
ADODB还有$connection->Affected_Rows()函数,传回受最后update或delete指令影响的数据列数, 及$recordset->Insert_ID()函数,传回最后因insert指令而自动产生的数据列编号,预先提醒大家,没有任何数据库有提供 这两个函数。
MetaTypes
你可以得到关于字段的更多信息,透过recordset的方法FetchField($fieldoffset)传回对象的3个属性:name,type,max_length。
举例说明:
$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
结果$f0->name的内容是'adata',$f0->type将是'date',假如max_length不知道,其内容将会是-1。
处理不同数据库的一个问题是,每一个数据库对于相同的数据型态会有不同的称呼,比如timestamp型态在某数据库中称为datetime,而另 一个数据库则称为time,所以ADODB提供MetaType($type,$max_length)函数来标准化下列的数据型态:
C: character and varchar types
X: text or long character (eg. more than 255 bytes wide).
B: blob or binary image
D: date
T: timestamp
L: logical (boolean)
I: integer
N: numeric (float, double, money)
在前面的例子中,
$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
$type = $recordset->MetaType($f0->type, $f0->max_length);
print $type; /* should print 'D' */
Select指令的Limit及Top支持
ADODB有个$connection->SelectLimit($sql,$nrows,$offset)函数让你撷取 recordset的部分集合,这是采用Microsoft产品中的SELECT TOP用法,及PostgreSQL与MySQL中的SELECT...LIMIT用法的优点,即使原来的数据库并没有提供此用法,本函数也仿真提供该使 用方式。
快取支援
ADODB允许你在你的档案系统中暂存recordset的数据,并且在$connection->CacheExecute($ secs2cache,$sql)及 $connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset)等设定的时间间 隔到达之后,才真正去做数据库的查询以节省时间。
PHP4 Session支持
ADODB也支持PHP4 session handler,你可以存放你的session变量在数据库中,相关功能请参考 http://php.weblogs.com/adodb-sessions
鼓励商业使用
假如你计划写商用的PHP应用软件来销售,你也可以使用ADODB,我们依据GPL来出版ADODB,也就是说你可以合法地在商用应用软件中引用,并保有你程序代码的所有权。强烈地鼓励ADODB的商业应用,我们自己内部也正以这个理由如此使用中。

PHP 相关文章推荐
PHP 简单日历实现代码
Oct 28 PHP
php HtmlReplace输入过滤安全函数
Jul 03 PHP
php json与xml序列化/反序列化
Oct 28 PHP
PHP 提取图片img标记中的任意属性的简单实例
Dec 10 PHP
生成随机字符串和验证码的类的PHP实例
Dec 24 PHP
php模拟post提交数据的方法
Feb 12 PHP
使用xampp搭建运行php虚拟主机的详细步骤
Oct 21 PHP
ThinkPHP中order()使用方法详解
Apr 19 PHP
joomla实现注册用户添加新字段的方法
May 05 PHP
PHP使用redis消息队列发布微博的方法示例
Jun 22 PHP
Yii框架页面渲染操作实例详解
Jul 19 PHP
PHP的new static和new self的区别与使用
Nov 27 PHP
php Http_Template_IT类库进行模板替换
Mar 19 #PHP
php auth_http类库进行身份效验
Mar 19 #PHP
php db类库进行数据库操作
Mar 19 #PHP
PHP Pear 安装及使用
Mar 19 #PHP
php 什么是PEAR?(第三篇)
Mar 19 #PHP
php 什么是PEAR?(第二篇)
Mar 19 #PHP
php 什么是PEAR?
Mar 19 #PHP
You might like
wiki-shan写的php在线加密的解密程序
2008/09/07 PHP
浅析php中jsonp的跨域实例
2013/06/21 PHP
destoon在360浏览器下出现用户被强行注销的解决方法
2014/06/26 PHP
php验证手机号码
2015/11/11 PHP
php制作简单模版引擎
2016/04/07 PHP
PHP通过微信跳转的Code参数获取用户的openid(关键代码)
2016/07/06 PHP
PHP实现的简单异常处理类示例
2017/05/04 PHP
JavaScript Base64编码和解码,实现URL参数传递。
2006/09/18 Javascript
jQuery 可以拖动的div实现代码 脚本之家修正版
2009/06/26 Javascript
通过Mootools 1.2来操纵HTML DOM元素
2009/09/15 Javascript
DOM_window对象属性之--clipboardData对象操作代码
2011/02/03 Javascript
javascript几个易错点记录
2014/11/26 Javascript
JavaScript动态添加列的方法
2015/03/25 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
Bootstrap每天必学之基础排版
2015/11/20 Javascript
jQuery简单获取键盘事件的方法
2016/01/22 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
2017/05/02 Javascript
带你了解session和cookie作用原理区别和用法
2017/08/14 Javascript
Vue中对比scoped css和css module的区别
2018/05/17 Javascript
详解如何快速配置webpack多入口脚手架
2018/12/28 Javascript
jQuery HTML设置内容和属性操作实例分析
2020/05/20 jQuery
编写Python小程序来统计测试脚本的关键字
2016/03/12 Python
python中字符串变二维数组的实例讲解
2018/04/03 Python
使用python将图片格式转换为ico格式的示例
2018/10/22 Python
如何将 awk 脚本移植到 Python
2019/12/09 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
使用CSS3制作响应式导航菜单的方法
2015/07/12 HTML / CSS
html5中如何将图片的绝对路径转换成文件对象
2018/01/11 HTML / CSS
Html5 canvas画图白板踩坑
2020/06/01 HTML / CSS
Banana Republic欧盟:美国都市简约风格的代表品牌
2018/05/09 全球购物
印度尼西亚值得信赖的第一家网店:Bhinneka
2018/07/16 全球购物
小学生倡议书范文
2014/05/13 职场文书
实习单位鉴定意见
2015/06/04 职场文书
SQL Server——索引+基于单表的数据插入与简单查询【1】
2021/04/05 SQL Server
粗暴解决CUDA out of memory的问题
2021/05/22 Python