ADODB类使用


Posted in PHP onNovember 25, 2006

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下删除字符串中HTML标签的函数
Aug 27 PHP
php at(@)符号的用法简介
Jul 11 PHP
PHP 分页原理分析,大家可以看看
Dec 21 PHP
PHP中数组的三种排序方法分享
May 07 PHP
php 批量替换html标签的实例代码
Nov 26 PHP
微信公众平台开发之天气预报功能
Aug 31 PHP
ThinkPHP数据操作方法总结
Sep 28 PHP
PHP弱类型的安全问题详细总结
Sep 25 PHP
php实现网页端验证码功能
Jul 11 PHP
php处理抢购类功能的高并发请求
Feb 08 PHP
Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
Apr 02 PHP
PHP设计模式入门之状态模式原理与实现方法分析
Apr 26 PHP
smarty静态实验表明,网络上是错的~呵呵
Nov 25 #PHP
PHP动态变静态原理
Nov 25 #PHP
smarty 原来也不过如此~~呵呵
Nov 25 #PHP
用PHP的ob_start();控制您的浏览器cache!
Nov 25 #PHP
PHP 常见郁闷问题答解
Nov 25 #PHP
PHP通用检测函数集合
Nov 25 #PHP
用PHP实现将GB编码转换为UTF8
Nov 25 #PHP
You might like
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
Javascript实现多彩雪花从天降散落效果的方法
2015/02/02 Javascript
使用RequireJS优化JavaScript引用代码的方法
2015/07/01 Javascript
Javascript中的作用域和上下文深入理解
2015/07/03 Javascript
javascript编程异常处理实例小结
2015/11/30 Javascript
jquery实现鼠标悬浮停止轮播特效
2020/08/20 Javascript
分享两款带遮罩的jQuery弹出框
2015/12/30 Javascript
简单实现jQuery进度条轮播实例代码
2016/06/20 Javascript
javascript-解决mongoose数据查询的异步操作
2016/12/22 Javascript
vue左侧菜单,树形图递归实现代码
2018/08/24 Javascript
Nodejs使用Mongodb存储与提供后端CRD服务详解
2018/09/04 NodeJs
详解Axios统一错误处理与后置
2018/09/26 Javascript
基于Vue实现图片在指定区域内移动的思路详解
2018/11/11 Javascript
[04:13]2014DOTA2国际邀请赛 专访DC目前形势不容乐观
2014/07/12 DOTA
[01:29:46]DOTA2上海特级锦标赛C组资格赛#1 OG VS LGD第二局
2016/02/27 DOTA
全面解读Python Web开发框架Django
2014/06/30 Python
Python实现随机选择元素功能
2017/09/14 Python
Python爬虫实例_城市公交网络站点数据的爬取方法
2018/01/10 Python
python实现log日志的示例代码
2018/04/28 Python
Python实现提取XML内容并保存到Excel中的方法
2018/09/01 Python
浅析python的Lambda表达式
2019/02/27 Python
Python中turtle库的使用实例
2019/09/09 Python
python列表生成器迭代器实例解析
2019/12/19 Python
python numpy 矩阵堆叠实例
2020/01/17 Python
使用tensorflow显示pb模型的所有网络结点方式
2020/01/23 Python
python,Java,JavaScript实现indexOf
2020/09/09 Python
加拿大健康、婴儿和美容产品在线购物:Well.ca
2016/11/30 全球购物
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
zooplus意大利:在线宠物商店
2019/08/07 全球购物
Visual-Click葡萄牙:欧洲领先的在线眼镜商
2020/02/17 全球购物
求职简历推荐信范文
2013/12/02 职场文书
安全资料员岗位职责
2013/12/14 职场文书
秘书专业自荐信范文
2013/12/26 职场文书
关于九一八事变的演讲稿2014
2014/09/17 职场文书
离婚案件答辩状
2015/05/22 职场文书
5种方法告诉你如何使JavaScript 代码库更干净
2021/09/15 Javascript