标签归档:adodb

adodb使用详解

1. 前言

ADODB 是 Active Data Objects Data Base 的简称,它是一种 PHP 存取数据库的函式组件。现在 SFS3 系统 (校园自由软件交流网学务系统) 计划的主持人陈莹光老师,决定采用此一组件,为了让更多有心参与该项目的伙伴们能够顺利加入发展的行列,小弟认为有必要把 ADODB 的中文入门介绍写出来,以方便伙伴们参考备查。

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

目前 ADODB 支持的数据库种类非常地多,例如: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 的简单用法:

<?php
// 引入 adodb 的 inc 档,才能呼叫 adodb 提供的函式
include('adodb/adodb.inc.php');

// 选择连接的数据库种类,以建立联机对象,
// 一旦对象建立,即可使用其成员函式来处理数据库。
// 以下 $conn 即此一物件(object)
$conn = &ADONewConnection('mysql');

// 要不要显示侦错讯息,false 不要,true 要。
// $conn->debug = false;

$conn->debug = true;

// 连接数据库
// 用法:$conn->Connect('主机', '使用者', '密码', '数据库');
// 用例:
$conn->Connect('localhost', 'piza', 'ooo123', 'test');

// 若欲采用持续性连接,上式可换用 PConnect:
// $conn->PConnect('localhost', 'piza', 'ooo123', 'test');

// 设定 sql 命令
$sql = "insert into t values ('abcde', 18)";

// 执行 sql 命令
$rs = $conn->Execute($sql);

// 检查执行结果,若 $rs == false,则呼叫 $conn 对象的成员函式 ErrorMsg()
if (!$rs) print $conn->ErrorMsg(); else print "OK!";

?>
结果如下:

---------------------------------------------
(mysql): insert into t values ("abcde",18)
---------------------------------------------
OK!

若把侦错关掉,即 $conn->debug=false,则结果如下:

OK!
以下,逐步为各位介绍:使用 ADODB 的重点方法。

2. 安装

ADODB 的首页在:http://php.weblogs.com/ADOdb,目前(2002/10/24)最新版是:2.42 版,可至 ADODB 下载或至台南县教网中心 FTP 下载。

安装 ADODB 的方法超极简单,只要下载、解压、放入适当位置,即可完成 ! 如下所示:

1. 下载:

$ ncftp ftp.tnc.edu.tw

cd sysop/ADODB

get adodb242.tgz

2. 解压:

假设我把 adodb242.tgz 放入 /var/www/html 中

$ cp adodb242.tgz /var/www/html

$ tar xvzf adodb242.tgz

如下所示:

adodb/adodb-cryptsession.php
adodb/adodb-csvlib.inc.php
adodb/adodb-errorhandler.inc.php
adodb/adodb-errorpear.inc.php
adodb/adodb-lib.inc.php
adodb/adodb-pager.inc.php
....以下省略....

现在,您在 /var/www/html/adodb 已安装好 ADODB 了。

3. 引入 ADODB

一旦安装好 ADODB,使用前,应把 ADODB 相关的含入文件引入您的程序中。adodb 目录放在任何位置无所谓,只要能指向正确路径文件名即可。一般而言,您的程序代码只须引入 adodb.inc.php。

作法如下:

在您的 PHP 程序中:

include('路径/adodb/adodb.inc.php');

include_once('路径/adodb/adodb.inc.php');
例:

若您的程序和 adodb 在同一目录下:

.
..
adodb/
something.php*

则:

include('adodb/adodb.inc.php');

即可。

若位置是在某一个目录 somedir 中:

.
..
adodb
somedir/something.php

则必须使用:

include('../adodb/adodb.inc.php');
除了 adodb.inc.php 这个含入档,ADODB 还提供许多 adodb-*.inc.php 的含入档,这些多半是为驱动某些数据库的特殊用法而设的。

若是引入 adodb-session.php 则可让您将 session 存入数据库中来维护运用。

若是引入 adodb-pager.inc.php,可方便您做分页显示。

若是引入 adodb-errorhandler.inc.php,可让您自订错误处理讯息。

若是含入 adodb-pear.inc.php,可让您使用 PHP4 的 PEAR DB 语法来使用 ADODB。此时,尚可使用 DSN 连接数据库的字符串设定。如 $dsn="mysql://piza:ooo123@localhost/test";

若是引入 tohtml.inc.php,可帮您在程序代码中,方便将取出的记录,转成 HTML 的表格(table)来显示。

若是引入 toexport.inc.php,可让您方便地输出 CSV 档或以 tab 分隔字段的数据文件。

若是引入 rsfilter.inc.php,可让您在使用记录之前,预做过滤处理。

若是引入 pivottable.inc.php,可让您使用 pivot table 功能(俗称 cross-tabulations)。

注意 ! adodb.inc.php 是一定要引入的,其它,则视您要使用那一个功能,再引入该含入档即可。

4. 选用数据库种类,建立联机对象

由于 ADODB 使用对象导向的作法,因此您在引入档之后,接着请视您后端数据库的种类,建立一个联机对象。作法如下:

以 MySQL 数据库为例:

$conn = &ADONewConnection('mysql');

注:NewADOConnection 和 ADONewConnection 是一样的,二者皆可使用。
上例中的 'mysql' 是指数据库的 drvier 的种类,ADODB 会据此呼叫对应的数据库 driver。

其它常用的 driver 有:access、ado、ado_access、ado_mssql、db2、vfp、ibase、borland_ibase、informix、 imformix72、mssql、oci8、odbc、postgres、postgres64、postgres7、sqlanywhere、 sybase....等等。

我们称建立的对象 $conn 为一 ADOConnection 对象,它代表与数据库的连接事务,皆透过这个对象来处理。ADOConnection 对象会提供许多处理的方法,以对象导向的说法,这些方法称为成员函式,这是外界存取此一对象的接口。

一旦联机对象建立之后,就有许多对象函式可供您使唤啦 ! 请看下一节的介绍。

5. 侦错模式

程序开发的过程,为了方便查出出现问题可能的地方,通常我们会打开侦错模式,俟程序功能确实稳定之后,再将它关闭。ADODB 提供侦错模式,存取数据库时,能显示其运作方式。

打开侦错模式,使用法:

$conn->debug=true
关闭侦错模式,使用法:

$conn->debug=false

6. 连接数据库

接着,使用 $conn 联机对象的 Connect 或 PConnect 函式来连接特定的数据库,此时必须提供 DSN (Data Source Names)相关数据,DSN 可能包括:主机名称、数据库使用者、数据库密码、数据库名称。不同的数据库种类,DSN 可能可以省略其中若干项。以 MySQL 而言,则上述四者都要提供。

该函式会传回 true 或 false,用以表示是否连接成功。

用例:

// 格式:$conn->Connect('主机', '使用者', '密码', '数据库');

$conn->Connect('localhost', 'piza', 'ooo123', 'test');

或者,采持续性连接:

// 格式:$conn->PConnect('主机', '使用者', '密码', '数据库');

$conn->PConnect('localhost', 'piza', 'ooo123', 'test');

若欲探查是否有联机成功,可用一个变量来接取传回值:

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$cok = $conn->Connect($mch, $user, $pwd, $database);

或者,采持续性连接:

$cok = $conn->PConnect($mch, $user, $pwd, $database);

if (!$cok) { echo "无法连接数据库 $database"; exit; }

7. 设定 sql 命令语法、执行 sql 命令

接下来,您就可以设计您要执行的 sql 命令语法,然后付诸执行。

$sql = "这里放 SQL 的命令语法";

$rs = $conn->Execute($sql);
其中,$rs 为回传的结果,若 $rs == false,则表示执行失败,您必须仔细检查一下。

您不一定要把命令语法放在 $sql 变量中,也可以直接放入 Execute( ) 括号中。若命令较短无妨,若命令较长,我建议您还是用一个变量 $sql 来设定命令字符串吧 !

下一节开始,为各位介绍 SQL 的基本命令,如:Insert、Select、Update、Delete 等等的用法。

8. 插入记录(Insert)

Insert 的用法如下:

// $name 为字符串,$year 为数字
$name='abcde';
$year=18;

// 插入一笔记录,命令的大小写无妨,但数据表 t 及变量则大小写有分别 !
$sql = "INSERT INTO t VALUES ('$name', $year)";

// $sql = "insert into t values ('$name', $year)"; 亦可。

// 执行
$rs = $conn->Execute($sql);

// 检查执行结果,进行错误处理;若正常,则继续其它动作....
if (!$rs) print $conn->ErrorMsg();

....以下省略....
ErrorMsg() 是错误显示的函式,它会取出错误讯息,并显示出来。

另外,ADODB 提供一种 记录集(RecordSet) 函式 GetInsertSQL(),可帮您产生 Insert 的语法。

例子如下:

<?php

// 引入 ADODB
include('adodb/adodb.inc.php');

// 建立联机对象
$conn = &ADONewConnection('mysql');

// 侦错
$conn->debug=true;

// DSN 四项基本数据设定
$mch="localhost";
$user="root";
$pwd="jack168";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 产生一笔空记录
$sql = "select * from t where year=-1";

$rs = $conn->Execute($sql);
// 用一个空数组来装要更新的数据
$r = array();

$r['name']='john';
$r['year']=28;

// 用 GetInsertSQL 函式来制作一个完整的 sql 命令,此 sql 命令放在 $insertSQL 中
$insertSQL = $conn->GetInsertSQL($rs, $r);

// 执行插入
$conn->Execute($insertSQL);

$conn->Close();
?>

侦错讯息如下:

-----------------------------------------------------------
(mysql): select * from t where year=-1
-----------------------------------------------------------
(mysql): INSERT INTO t ( name, year ) VALUES ( 'john', 28 )
-----------------------------------------------------------

9. 取出记录(Select)

Select 的用法如下:

<?php

// 引入 ADODB
include('adodb/adodb.inc.php');

// 建立联机对象
$conn = &ADONewConnection('mysql');

// 不侦错
$conn->debug=false;

// DSN 四项基本数据设定
$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 执行 Select 由表格 t 取出数据,
// 它会传回一个 ADORecordSet 记录集对象 $rs (RecordSet)
// 实际上 $rs 是一个 cursor 指标,它拥有目前的记录(row 或称 record),
// 该记录的所有字段数据的内容,存放在 fields 这个数组之中
// ,以数字为索引,第一个由 0 开始
$rs = &$conn->Execute('select * from t');

// 若 $rs 为 false,则秀出错误讯息
if (!$rs) {
print $conn->ErrorMsg();
} else {

// 当尚未到达 记录集 $rs 的结束位置(EOF:End Of File)时,(即:还有记录尚未取出时)
while (!$rs->EOF) {
// 秀出所有字段,$FieldCount() 会传回字段总数
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
print $rs->fields[$i] . " ";
}

// 移至下一笔记录
$rs->MoveNext();

// 换列
echo "<br>\n";
}
}

$rs->Close(); // 可不用
$conn->Close(); // 可不用
?>

$rs->fields[] 数组是由 PHP 的数据库扩展功能产生的,某些扩展功能并不支持使用字段名称当作索引。

若欲使用名称当作索引,也就是俗称的 hash 或 associative arrays,则需使用全域变量 $ADODB_FETCH_MODE 加以指定。

以下设定:使用数字索引 $ADODB_FETCH_MODE= ADODB_FETCH_NUM;
以下设定:使用名称索引 $ADODB_FETCH_MODE= ADODB_FETCH_ASSOC;
下面是使用名称索引的例子:

<?php

// 引入 ADODB
include('adodb/adodb.inc.php');

// 建立联机对象
$conn = &ADONewConnection('mysql');

// 不侦错
$conn->debug=false;

// DSN 四项基本数据设定
$mch="localhost";
$user="root";
$pwd="jack168";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 执行 sql 之前,指定使用名称索引
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;

// 执行 Select,它会传回一个 ADORecordSet 记录集对象 $rs
// 实际上 $rs 是一个 cursor 指标,它拥有目前的记录内容,
// 该记录存放在 fields 这个数组之中
$rs = &$conn->Execute('select * from t');

// 若 $rs 为 false,则秀出错误讯息
if (!$rs) {
print $conn->ErrorMsg();
} else {

// 当尚未到达记录集结束位置(EOF)时,
while (!$rs->EOF) {
// 秀出所有字段

print $rs->fields['name'] . " " . $rs->fields['year'];

// 移至下一笔记录
$rs->MoveNext();

// 换列
echo "<br>\n";
}
}

$rs->Close();  // 可不用
$conn->Close(); // 可不用
?>

10. 取出记录(使用 FetchRow)

这里示范 FetchRow 的用法:

$sql = "select * from t";

$rs = $conn->Execute($sql);

if ($rs) {
while( $ar = $rs->FetchRow() ) {
print $ar['name'] ." " . $ar['year'];
print "<br>\n";
}

}
FetchRow() 会将取出的记录传回,您可用一个 array 来接取。

注意 ! 使用 FetchRow() 就不必再用 MoveNext(),FetchRow 内部会自动完成移至下一笔记录的动作。

11. 更新记录(Update)

您可以用传统的方式:

$sql ="UPDATE t SET name='john', year=28 WHERE year=18";
$conn->Execute($sql);

也可以用以下这种方式:

<?php

// 引入 ADODB
include('adodb/adodb.inc.php');

// 建立联机对象
$conn = &ADONewConnection('mysql');

// 侦错
$conn->debug=true;

// DSN 四项基本数据设定
$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 选择要更新的那一笔记录
$sql = "select * from t where year=18";

$rs = $conn->Execute($sql);
// 用一个空数组来装要更新的数据
$r = array();

$r['name']='john';
$r['year']=28;

// 用 GetUpdateSQL 函式来制作一个完整的 sql 命令,此 sql 命令放在 $updateSQL 中
$updateSQL = $conn->GetUpdateSQL($rs, $r);

// 执行更新
$conn->Execute($updateSQL);

$conn->Close();
?>

侦错讯息如下:

-------------------------------------------------------------
(mysql): select * from t where year=18
-------------------------------------------------------------
(mysql): UPDATE t SET name = 'john', year = 28 WHERE year=18
-------------------------------------------------------------

12. 删除记录(Delete)

删除记录很简单,采传统方式即可: $sql = "DELETE FROM t WHERE year=18";

$rs = $conn->Execute($sql);

13. 使用字段对象(Field Objects)

这里示范字段对象 FetchField 的用法,用以取得字段名称及字段型态:

$sql = "select * from t";

$rs = &$conn->Execute($sql);

if ($rs) {
while (!$rs->EOF) {
// 取出第二个字段
$f = $rs->FetchField(1);

// 印出字段名称 及 字段型态
print $f->name . ":" . $f->type;

$rs->MoveNext();

print "<br>\n";
}
}

另外,ADODB 提供一个 RecordSet 函式 MetaType(),可将原始的字段型态转成一般型态代码:

C : 字符
X : text
B : blob
D : 日期
T : timestamp
L : 布尔值或位
I : 整数
N : 数字型态,包括:自动增加、数值、浮点数、实数及整数
R : serial、自动增加

用例:

$f = $rs->FetchField(1);

// 印出字段名称 及 字段型态的代码
print $f->name . ":" . $rs->MetaType($f->type);

14. 简单分页(Pager)

ADODB 提供一种简单分页显示记录的方法,使用前,要将 adodb-pager.inc.php 引入。

<?php

include('adodb/adodb.inc.php');

// 引入分页功能
include('adodb/adodb-pager.inc.php');

// 启动 session
session_start();

$db = ADONewConnection('mysql');

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$db->Connect($mch, $user, $pwd, $database);

$sql = "select * from t";

// 产生 pager 对象
$pager = new ADODB_Pager($db, $sql);

// 每一页秀 5 笔记录
$pager->Render($rows_per_page=5);

?>
结果如下:

Figure 1. 简单分页功能
每页显示记录的数目是由 Render() 来控制的,若没有传入指定的 row 数给 Render(),默认值每页秀 10 笔。

另外,字段名称也可以改变,如下示范:

<?php

include('adodb/adodb.inc.php');

// 引入分页功能
include('adodb/adodb-pager.inc.php');

// 启动 session
session_start();

$db = ADONewConnection('mysql');

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$db->Connect($mch, $user, $pwd, $database);

$sql = "select name as '姓名', year as '年纪' from t";

// 产生 pager 对象
$pager = new ADODB_Pager($db, $sql);

// 每一页秀 5 笔记录
$pager->Render($rows_per_page=5);
?>

结果如下:

Figure 2. 改变字段名称

15. 输出 CSV 档

ADODB 提供输出 CSV 档的方法,使用前,要将 toexport.inc.php 引入。

<?php

include('adodb/adodb.inc.php');

// 引入输出 CSV 文件功能
include('adodb/toexport.inc.php');

$db = ADONewConnection('mysql');

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$db->Connect($mch, $user, $pwd, $database);

$sql = "select name as '姓名', year as '年纪' from t";

$rs = $db->Execute($sql);

// 秀出 CSV 格式
print rs2csv($rs);
?>

结果如下:

姓名,年纪
abcde,45
yyy,20
ppp,34
mmm,13
hhh,41
rrr,65
kkk,29
miso,154
sss,89
abc,18
abcde,0
uyt,58
john,28

也可用 tab 分隔字段,使用 rs2tab 方法如下:

print rs2tab($rs, false);

注: false 表示不显示字段名称

结果如下:

abcde  45
yyy    20
ppp    34
mmm    13
hhh    41
rrr    65
kkk    29
miso   154
sss    89
abc    18
abcde  0
uyt    58
john   28

若是 print rs2tab($rs, true);
结果如下:

姓名    年纪
abcde   45
yyy     20
ppp     34
mmm     13
hhh     41
rrr     65
kkk     29
miso    154
sss     89
abc     18
abcde   0
uyt     58
john    28

也可以将结果由标准输出(STDOUT)显示,使用 rs2tabout 方法如下:

print rs2tabout($rs);
执行结果如下:

Figure 1. 在console中显示结果
也可以存成 CSV 档:

// 档案路径
$path = "/tmp/test.csv";

// 开档供写入
$fhd = fopen($path, "w");

// 若开档成功
if ($fhd) {

// 则写入 CSV
rs2csvfile($rs, $fhd);

// 也可以使用 rs2tabfile($rs, $fhd);

// 关档
fclose($fhd);
}

结果如下:

[ols3@p web]$ cat /tmp/test.csv
姓名,年纪
abcde,45
yyy,20
ppp,34
mmm,13
hhh,41
rrr,65
kkk,29
miso,154
sss,89
abc,18
abcde,0
uyt,58
john,28

16. 取出一定笔数的记录 (使用 SelectLimit)

ADODB 提供一个 ADOConnect 函式 SelectLimit,可供您取出一定笔数的记录,用法如下:

$conn->Connect($mch, $user, $pwd, $database);

rs = $conn->SelectLimit("Select * from t", 3, 1);
//                             取出 3 笔、在第 1 笔之后

// 秀出这 3 笔记录
if ($rs) {
while( $ar = $rs->FetchRow() ) {
print $ar['name'] ." " . $ar['year'];
print "<br>\n";
}

}
上式是说:在第 1 笔记录之后,取出 3 笔,也就是第 2、3、4 笔记录。

结果如下:

--------------------------------------
(mysql): select * from t LIMIT 1,3
--------------------------------------

注意 ! SelectLimit 的写法刚好和 MySQL 语法相反 !

PHP中 ADOdb 类库应用(三):参考手册(4)

ADORecordSet(资料集)

当一个SQL指令成功的被 ADOConnection->Execute($sql)执行后,一个 ADORecordSet 对象会被回传回来。这个对象提供了一个虚拟的指针,所以我们可以移动它,从一笔到一笔。也提供一些函数,以取得字段信息和字段类别,并有协助函数去格式化结果,以展示给使用者看。

ADORecordSet 属性

fields: 包含了目前记录的数组。不是关连式数组,但它的索引值是从 0 字段数 - 1。请参考函数 Fields ,这个函数的动作就像是一个关连式数组。

dataProvider: 连结数据库的底层机制,正常设定为 native ,除非是使用 odbc ado blobSize: 一个 char , string 或者 varchar object 在被转成 Blob 前的最大长度(Blob 在显示时应该使用 textarea)。其它请参考 MetaType 函数。

sql: 储存了建立本数据集所使用的 sql 指令。

canSeek: 如果 Move() 函数有作用,会被设成 true

EOF: 当指针被移动到最后一笔时,这个值会被设定成 true

ADORecordSet 函数

ADORecordSet( )

建构函数。一般来说你不需要自己呼叫这个函数。

GetAssoc([$force_array])

如果字段数大于 2 ,那么从资料集中产生一个关连式数组。这个数组是从目前的指针起一直到档尾(EOF)。这个资料集的第一个字段会成为数组的索引。如果字段数刚好是2,当这数组被每一个键值所建立时,那么索引会直接对应到值,除非 $force_array 被设成 true

范例:

以下是我们资料集的资料:

1: Apple, Fruit, Edible
2: Cactus, Plant, Inedible
3: Rose, Flower, Edible

GetAssociation 将会产生一个如下的关系型数组:

Apple => [Fruit, Edible]
Cactus => [Plant, Inedible]
Rose => [Flower,Edible]

回传值:

关连式数组,错误则传回 false

GetArray([$number_of_rows])

从目前指针位置产生一个数组,索引值从 0 $number_of_rows - 1 。如果 $number_of_rows 没有被定义,那会到档尾(EOF)

GetRows([$number_of_rows])

GetArray() 的同义函数,是为了与 Microsoft ADO 兼容才有的。

GetMenu($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])

建立一个 HTML 选单 (<select><option><option></select>) 。资料集的第一栏 (fields[0]) 将会作为 <option> 里的显示字符串。如果资料集有超过一个以上的字段,第二栏 (fields[1]) 将设定成回传给WEB服务器的值( value)。选单将被给予 $name 为名称。

如果 $default_str 被定义了,那么如果 $default_str == fields[0] 那么这个字段将会被选取。 如果 $blank1stItem true ,那第一个选项将会是空值。$Default_str 在对于可多选清单盒时,可以是一个数组。

要产生一个选单区,设定 $size 为一个非 0 (或者传入 $default_str 为一个数组)。如果 $multiple_select true ,那么一个选单区将会被产生成有 $size 个项目可见的选单(如果 $size == 0 那预设为 5 ),而且ADODB将会回传一个数组给服务器。最后,你可以使用 $moreAttr 去增加其它的属性,像是 javascript 或样式表。

选单范例 1: GetMenu('menu1','A',true) 将会产生一个像这样的选单 : A B C 这里的资料 (A,1), (B,2), (C,3). 请参考 范例 5

选单范例 2: 相同的资料, GetMenu('menu1',array('A','B'),false) 将会产生一个 A B 被选取的选单 : A B C GetMenu2($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])

近似于 GetMenu ,除了 $default_str 将会和 fields[1] 做比对也就是选项值。 选单范 3: 给予在范例 2 里的数据 , GetMenu2('menu1',array('1','2'),false) 将会产生一个选单,AB将会被选取。然而,这一次的被选取的比对基准是第二个字段,也就是存放要被回传给服务器里的值。 UserDate($str, [$fmt])

转换日期字符串 $str 为另一个格式,UserDate 呼叫 UnixDate 来解译 $str ,而 $fmt 默认值是 Y-m-d

UserTimeStamp($str, [$fmt])

转换时间字符串 $str 为另一个格式,时间字符串格式是 Y-m-d H:i:s 像是 "2002-02-28 23:00:12"UserTimeStamp 呼叫 UnixTimeStamp 来解译 $str ,而 $fmt 默认值为 Y-m-d H:i:s

UnixDate($str)

将日期字符串 $str 解译,并且转换成 unix mktime 格式( 1970.01.01 00:00:00 起到现在的秒数)后传回。预设日期是以 Y-m-d H:i:s 格式来传入的。而对于 Sybase Microsoft SQL Server 而言 M d Y 也是可以接受的(三个字符的月份表示法是被一个全域数组所控制的,这个部份可能需要在地化 )

1.91 版起,这个函数存在于 ADORecordSet ADOConnection两个地方。

UnixTimeStamp($str)

将时间字符串 $str 解译,并且转换成 unix mktime 格式( 1970.01.01 00:00:00 起到现在的秒数)后传回。预设日期是以 Y-m-d H:i:s 格式来传入的。而对于 Sybase Microsoft SQL Server 而言 M d Y 也是可以接受的(三个字符的月份表示法是被一个全域数组所控制的,这个部份可能需要在地化 )

1.91 版起,这个函数存在于 ADORecordSet ADOConnection两个地方。

MoveNext( )

移动内部指针到下一笔,fields 数组将会自动的更新。如果不能移动,会回传 false 值,其它情况则会回传 true

范例

$rs = $db->Execute($sql);
if ($rs) 
        while (!$rs->EOF) {
                 ProcessArray($rs->fields);
                 $rs->MoveNext();
         } 

Move($to)

移动内部指针到指定的列 ($to) 列数是零基的,例如,0是第一列。fields 数组将会自动更新。对于不支持内部卷动的数据库,ADODB将会自动仿真卷动。部份数据库不支持向后卷动。对大多数的数据库言,如果 $to 的位置在 EOF 之后,$to 将会被移动到资料集的最后一笔。有些无名的数据库使用 odbc 时,可能会没有动作。

注意:这个函数使用了绝对寻址,不像 Microsoft ADO

回传值是 true 或是 false。如果是 false ,这个内部指针在大多数的实际运作上并没有移动,所以 AbsolutePosition() 将会回传指针在执行 Move() 之前最后的位置

MoveFirst()

实际上是呼叫 Move(0) 。注意,有一些数据库并不支持这个函数。

MoveLast()

实际上是呼叫 Move(RecordCount() - 1)。注意,有一些数据库并不支持这个函数。

GetRowAssoc($toUpper=true)

这个函数并不能持续的以理想的方式维持关连数组的内容(每换一笔记录,就要重新执行一次)。使用 $ADODB_FETCH_MODE 共享变量来替代它。

回传一个包含了目前记录的关连式数组,数组的索引值就是字段名。字段名全都是大写的,以便存取。要取得下一笔记录,你要呼叫 MoveNext()

范例 :
Array ( [ID] => 1 [FIRSTNAME] => Caroline [LASTNAME] => Miranda [CREATED] => 2001-07-05 )

注意:不要同时使用 GetRowAssoc() $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC 。因为他们有相同的功能,会彼此交互干扰。

AbsolutePage($page=-1)

回传目前的页码,需要先呼叫 PageExecute() / CachePageExecute()

AtFirstPage($status='')

如果在第一页,回传 true (1基式),需要先呼叫 PageExecute() / CachePageExecute()

AtLastPage($status='')

如果在最后一页,回传 true (1基式),需要先呼叫 PageExecute() / CachePageExecute()

Fields($colname)

不鼓励使用,请改以 $ADODB_FETCH_MODE 取代。

当使用原生函数库时,有些数据库函数回传具名及索引双数组( MySQL)GetRowAssoc() 并不回传结合了具名及索引的数组元素。

本函数回传由 $colname 所指栏名,在目前记录里的的字段值。

字段名区分大小写。

FetchRow()

回传目前记录内容的数组,如果是文件尾(EOF),回传 false 。注意:不要把 FetchRow MoveNext() 混用。 用法 :

$rs = $db->Execute($sql);
if ($rs)
         while ($arr = $rs->FetchRow()) {
            # process $arr
         }

FetchInto(&$array)

设定 $array 到目前的记录里。如果在文件尾(EOF),回传 PEAR_Error 对象。如果成功,回传 1 (DB_OK 常数)

如果 PEAR 未定义,当 EOF 时回传 false FetchRow() 很容易使用,请参考之前的例子。

FetchField($column_number)

回传一个对象,包含了所指字段的名称,类别及最大长度。如果最大长度不能被明确决定,将会回传 -1 行号是以 0 基为计算起点的。

FieldCount( )

回传资料集里字段数。

RecordCount( )

回传资料集里的记录笔数。如果无法从数据库驱动程序API里取得正确的数字,ADODB将会把所有的记录内容,存放在内存里,等全部取完后,再回传记录总笔数。这个内存可以藉由设定全域变量 $ADODB_COUNTERECS = false 而被取消(基于执行效能的理由)。当取消后,对某些数据库,RecordCount() 将会回传 -1 。相关支持状况,请参考前面的数据库支持表有详细的说明。

RowCount RecordCount 是同义函数。

PO_RecordCount($table, $where)

回传在资料集里的记录笔数。如果数据库不支持,那么将回传对 $table 资料表下达以 $where 为条件的 SELECT COUNT(*) 指令后回传的值。

$numrows = $rs->PO_RecordCount("articles_table", "group=$group");

会回传数据库执行 SELECT COUNT(*) FROM articles_table WHERE group=$group 的结果。

FetchObject($toupper=true)

回传目前的记录为一个对象。如果 $toupper true ,那么对象字段名将会设为大写。注意:较新的 FetchNextObject() 是取得记录对象较被建议的方式,请参看后续说明。

FetchNextObject($toupper=true)

取得目前的记录成一个对象,并且自动移动到下一个记录。如果在档尾,回传 false 。如果 $toupper true ,那么对象字段名将会设为大写。

$rs = $db->Execute('select firstname,lastname from table');
if ($rs) {
         while ($o = $rs->FetchNextObject()) {
                 print "$o->FIRSTNAME, $o->LASTNAME<BR>";
         }
}

在使用 FetchNextObject() 时会影响效能,如果效能很重要,你应该使用 fields[] 数组来存取。

CurrentRow( )

目传目前资料集的记录编号,0 表示是第一笔。

AbsolutePosition( )

CurrentRow 是相同的函数,是为了和 ADO 兼容而存在的。

MetaType($nativeDBType[,$field_max_length],[$fieldobj])

设定资生数据库里的原生型别 $nativeDBType 为那一种通用资料型别,以及它的最大长度。请注意,如果长度未知,可以设为 -1 。字段对象可以使用 $fieldobj 传入。这对于像是 mysql 这一类字段对象有较多属性的数据库来说,是很有用的。 使用字段 blobsize 及比较 $field_max_length 去决定目前的字段是否为 blob 回传值:

         C: character 字段,应该使用 <input type="text"> 标记来取值。

         X: 文字字段(Text) , 长文字字段,使用 <textarea> 标记来显示资料。

         B: Blob 字段或者大型的二位对象(像程序,图文件等)

         D: 日期字段

         T: 时间字段

         L: 逻辑字段(真假值)或位字段

         N: 数字字段,包含自动进位、编号、整数、浮点数、实数等。

         I: 整数字段

         R: 序列字段,包含了序列、自动增进整数,只对被选择的数据库作用。

Close( )

关闭目前的资料集。

PHP中 ADOdb 类库应用(三):参考手册(2)

ADOConnection 主要函数
ADOConnection( )

建构函数,请不要直接呼叫,使用 ADONewConnection() 来代替。

Connect($host,[$user],[$password],[$database])

对服务器或资料来源 $host 非持续性连结,使用者认证代码为 $user ,密码为 $password ,如果服务器支持多数据库,则指定连结到数据库 $database。

连结成功回传 true , 失败则回传 false 。

注意:如果你使用的是 Microsoft ADO,而非 OLEDB,你可以设定 $database 参数为你正在使用的 OLEDB 资料供应器。

PostgreSQL:另一种选择性的连结方法是将标准的PostgreSQL连结字符串放在 $host 参数里,那么其它的参数都会被呼略。

对于 Oracle 及 Oci8,有两个方法可以连结。第一,使用你定义的区域 tnsnames.ora 里的 TNS 名称,将这个名称放在 $database 参数里,然后将 $host 设为 false。另一种方法,设定 $host 为服务器,而 $database 则设成数据库 SID ,这将会不透过 tnsnames.ora 连结。

范例:

$conn->Connect(false, 'scott', 'tiger', 'name_in_tnsnames'); # 使用 tnsnames.ora
$conn->Connect('server:1521', 'scott', 'tiger', 'OracleSID'); # 不使用 tnsnames.ora
PConnect($host,[$user],[$password],[$database])

对服务器或资料来源 $host 持续性连结,使用者认证代码为 $user ,密码为 $password ,如果服务器支持多数据库,则指定连结到数据库 $database。

连结成功回传 true , 失败则回传 false 。其它资料请参考 Connect()。

Execute($sql,$inputarr=false)

执行 SQL 指令 $sql ,如果成功,就回传一个对应的 ADORecordSet 对象。要注意的是这个指令如果执行成功时,一定会回传一个数据集,即使是执行 insert 或 update 指令也一样。

回传对应的 ADORecordSet 对象。例如,如果连结的是 mysql ,那么 ADORecordSet_mysql 将会被回传。当SQL指令执行失败时会回传 false 值。

$inputarr 参数则用来做为传入的结合变量。以下是 Oracle 的范例:

$conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val));

另一个例子,使用 ODBC ,以 '?' 符号做为协议。

$conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));
结合变量(Binding variables)
变量的结合可以加速SQL指令编译及快取的速度,产生较佳的效能。目前只有 Oracle 及 ODBC 支持变量结合。 ODBC 类的 ? 结合在不支持的数据库里,是以仿真的方式来做到的。

变量结合在 odbc 及 oci8po 驱动程序里的用法。

$rs = $db->Execute('select * from table where val=?', array('10'));
变量结合在 oci8 驱动程序里的用法。

$rs = $db->Execute('select name from table where val=:key',array('key' => 10));
CacheExecute($secs2cache,$sql,$inputarr=false)

类似于 Execute 函数,除了将资料集暂存在 $ADODB_CACHE_DIR 指定的目录里 $secs2cache 秒外。如果 CacheExecute() 被相同的参数、数据库、使用者ID及密码,而且快取也没有过期,那么快取中的资料集将会被传回。

include('ADOdb.inc.php');
include('tohtml.inc.php');
$ADODB_CACHE_DIR = '/usr/local/ADOdbcache';
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
$rs = $conn->CacheExecute(15, 'select * from table'); # 快取15秒
rs2html($rs); /* recordset to html table */
另外,从ADODB 1.80 版起,$secs2cache 参数成为选择性(也就是可以不加)

       $conn->Connect(...);
        $conn->cacheSecs = 3600*24; // cache 24 hours
        $rs = $conn->CacheExecute('select * from table');
如果 CacheExecute() 被多次呼叫,而且资料集也持续在快取中,$secs2cache 参数不会延长被快取的资料集保留时间(因为会被呼略掉),CacheExecute()只能使用在 SELECT 指令上。

效能备注:我曾经作了一些效能测试,并且发现这些快取的效益极为显著。尤其是在数据库服务器运作效率慢于WEB服务器或数据库的负荷非常重的时候。ADODB的快取好在它减少了数据库服务器的负荷。当然,如果你的数据库服务器负荷不大,而且运作速度也比WEB服务器快,那快取反而会降低效能。

SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)

执行成功会回传一个资料集。完成一个SELECT指令,类似于 PostgreSQL中 SELECT 指令里的LIMIT $numrows OFFSET $offset 宣告。

在 PostgreSQL,SELECT * FROM TABLE LIMIT 3 将会只传回从头开始的三笔记录。相同的,$connection->SelectLimit('SELECT * FROM TABLE',3)也有同样的意思。

而 SELECT * FROM TABLE LIMIT 3 OFFSET 2 将会回传记录 3,4及5三笔(也就是在记录2之后,回传三笔记录)。相同的,在ADODB里是以 $connection->SelectLimit('SELECT * FROM TABLE',3,2) 来做的。

要注意,LIMIT宣告,在MySQL里是相反位置的。你可以设定 $connection->SelectLimit('select * from table',-1,10) 去取得从第11笔起到最后一笔的记录。

最后一个参数 $inputarr 是针对支持变量结合功能的数据库,像 Oracle oci8。这个大大的减少了 SQL 编译的负荷。底下是 Oracle 范例:

$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val));

CacheSelectLimit($secs2cache, $sql, $numrows=-1,$offset=-1,$inputarr=false)
类似于 SelectLimit,除了将资料集暂存在 $ADODB_CACHE_DIR 指定的目录里 $secs2cache 秒外。

自 1.80版起,$secs2cache成为了选择性参数:

$conn->Connect(...);
        $conn->cacheSecs = 3600*24; // 快取24小时
        $rs = $conn->CacheSelectLimit('select * from table',10);
CacheFlush($sql)

更新(删除)以 $sql 指令存放在 $ADODB_CACHE_DIR 指定目录内的全部快取资料集。如果你企图更新所有的快取数据集,请执行如下的PHP指令码(仅针对 Unix 有效):system("rm -f find ".ADODB_CACH_DIR." -name ADODB_*.cache") ;

ErrorMsg()

回传最后状态或是错误讯息。即使没有错误发生,本函数也会回传一个字符串。一般情况下,你不需要呼叫这个函数,除非ADODB函数因为错误状态回传了false值。

注意:如果 debug 旗标被激活了,SQL 错误讯息将会在Execute函数被呼叫时发生错误后出现。

ErrorNo()

回传最后的错误号码。注意一点,旧版本的 PHP(4.0.6以前),不支持ODBC的错误编号。一般情况下,你不需要呼叫这个函数,除非ADODB函数因为错误状态回传了false值。

GenID($seqName = 'ADOdbseq',$startID=1)

产生一个顺序号码(在mssql是一个整数值)。对 interbase,mysql,postgresql,oci8,oci8po,ODBC核心类驱动程序(如 access,vfp,db2等等) 都支持。使用 $seqName做为顺序名。如果数据库没有值,那么GenID()将会自动为你产生一个序号(产生使用者 id 时允许如此),换句话说,你必需自行建立序号。

如果你的数据库驱动程序要仿真序号,资料表的名称就是序号名(sequence name),而这个资料表必需有一个字段"id",而其资料型别为整数,或你需要更大些的 numeric(16)。

对于没有支持序号原生功能的ODBC及数据库(如 mssql,mysql),我们对每一个序号建立一个资料表。如果序号没有被预先定义,那启如的号码值就设定成 $startID。

注意,mssql驱动程序的 GenID()会产生一个16位的GUID。自1.90版起,我们将回传整数。

UpdateBlob($table,$column,$val,$where)

允许你以 $where 条件储存一个BLOB(存在 $val里的)值到 $table 里的 $column 字段。

例:

        # for oracle

        $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())');
        $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
        # non oracle databases
        $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
        $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
如果成功,会回传 true ,否则回传 false 值。目前有 MySQL, PostgreSQL, Oci8, Oci8po 及 Interbase 支持。其它驱动程序可能有效,仍在持续开发中。

要注意,在PHP 4.1.0 以前的版本,当 Interbase的 blob 值被 SELECT 取回值时,它仍需要被译码,请使用 $connection->DecodeBlob($blob); 以还原它的内容。

UpdateClob($table,$column,$val,$where)

允许你以 $where 条件储存一个BLOB(存在 $val里的)值到 $table 里的 $column 字段。类似于 UpdateBlog,但主要针对文字大型档案对象。

例:

        # for oracle

        $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())');
        $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');

        # non oracle databases
        $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');
        $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');
UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')

如同 UpdateBlob ,但我们将值改成一个档案路径,将整个档案存入。

成功回传 true 否则为 false。

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false)

建立一个 SQL 以更新一个被给予的资料集 $rs ,被修改的字段存放在数组 $arrFields中(这个数组必需是具名数组,字段名为索引,值为修正值),会与原来的资料集做一个比较,如果 $forceUpdate被设为 true,那么即使 $arrFields与 $rs->fields完全相同,也会产生出更新的SQL指令。资料集必需在连结状态。$magicq 被用于指出魔术引号功能是否被激活。

GetInsertSQL(&$rs, $arrFields,$magicq=false)

建立一个 SQL 以新增一笔记录到被给予的资料集 $rs。这个查询必需是在连结状态。$magicq 被用于指出魔术引号功能是否被激活。

PageExecute($sql, $nrows, $page, $inputarr=false)

使用资料集的页码功能,参数 $page 是以 1 为启使值,请参考范例 8.

CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false)

使用资料集的页码功能,参数 $page 是以 1 为启使值,请参考范例 8.PageExecute 的快取版。

Close( )

关闭数据库的连结。PHP4 以数据库连结结束时不需要特别去清除而享有盛名,因为其参考计数机制会自动帮我们清除掉。

BeginTrans( )

启始一笔交易。会关闭自动结案功能。执行成功会回传 true 。如果不支持交易功能,部份数据库会一直传回 false 值。Interbase,Oracle 及 MSSQL 支持交易机制。请注意,因为 PHP 4.02 版的臭虫,交易支持在微软的 ADO 上是无效的。你必需使用你关连式数据库的原生交易支持功能。当连结结束时,任何开启的交易都会被还原。

CommitTrans( )

成功的结束一次交易。如果成功,回传 true。如果数据库并不支持交易功能,那么就只会传回 true ,以表示资料总是交易成功的。

RollbackTrans( )

结束一次交易,恢复所有改变。执行成功会回传 true 。如果数据库并不支持交易功能,那么就只会传回 false ,以表示资料总是不能恢复。

GetOne($sql)

Executes the SQL and returns the first field of the first row as an array. The recordset and remaining rows are discarded for you automatically. If an error occur, false is returned.

执行SQL指令,并且以数组的方式回传第一笔记录的第一个字段。资料集及其余的记录将会被自动清除,如果发生错误,就回传 false 值。

译者注:这个功能在验证某笔记录在不在特别有用,可以减少系统内存及资源的用量。

GetRow($sql)

执行SQL指令,并且以数组的方式回传第一笔记录。资料集及其余的记录将会被自动清除,如果发生错误,就回传 false 值。

Prepare($sql )

预先编译一个SQL查询,以便于重复执行。如果有任何语法错误,Prepare()不会显示任合错误,但允许 Execute() 去取得及显示错误。内部实作支持 interbase ,oci8 及选择性的 ODBC-based 驱动程序。其余的都是以仿真的方式支持。在仿真的情况下,使用 Prepare() 对效能的增进没有任何效果。

回传一个包含了原始描述为第一个数组元素的数组,其余的元素内容则视驱动程序而定。如果有错误或是仿真方式的 Prepare(),会回传原来的 $sql 字符串。那是因为所有的错误处理都被集中到 Execute() 里去了。

范例 :

$stmt = $DB->Prepare('insert into table (col1,col2) values (?,?)');
for ($i=0; $i < $max; $i++)
$DB->Execute($stmt,array((string) rand(), $i));
PrepareSP($sql)

在 mssql 驱动程序里,预编译预储程序必需要透过一个特别的函数来呼叫 mssql_init(),这个动作目前由本函数来处理了。PrepareSP() 可以在所有的驱动程序由被呼叫,而且以呼叫 Prepare() 的方式来仿真。使用范例请参考以下的 Parameter() 说明。

和上面的 Prepare() 回传一样的数组或 $sql 字符串。

Parameter($stmt, $var, $name, $isOutput=false, $maxLen = 4000, $type = false )

在运作中增加一个结合参数。目前兼容于 Microsoft SQL 及 Oracle oci8。以下是参数说明:
$stmt 由 Prepare() 或 PrepareSP() 回传的指令。
$var 要结合的 PHP 变量。
$name 要结合的预储程序的变量名。
[$isOutput] 设定参数传导的方向,0/false = IN 1=OUT 2= IN/OUT 。 在 oci8 中这个参数会被忽略,因为驱动程序会自动侦测。
[$maxLen] 参数变量的最大长度。
[$type] 参考 mssql_bind 及 ocibindbyname 在 PHP.NET 的文件说明以取得更多正确值的信息。

在 mssql,$opt 可以被下列的元素所影响:mssql_bind and ocibindbyname 。 例如 ;

# @RETVAL = SP_RUNSOMETHING @myid,@group
$stmt = $db->PrepareSP('SP_RUNSOMETHING');
# note that the parameter name does not have @ in front!
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
# return value in mssql - RETVAL is hard-coded name
$db->Parameter($stmt,$ret,'RETVAL',true);
$db->Execute($stmt);
一个 oci8 的例子:

# 对于 oracle, Prepare 及 PrepareSP 是相同的
$stmt = $db->PrepareSP(
        "declare ret integer;
     begin
                :RETVAL := SP_RUNSOMETHING(:myid,:group);
     end;");
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
$db->Parameter($stmt,$ret,'RETVAL',true);
$db->Execute($stmt);
请注意,在 oci8 及 mssql 间只有语法上的不同,那是各数据库实作 SQL 语法问题,ADODB 对于这一部份无能为力。

如果 $type 参数被设定成 false 。在 mssql ,$type 将会动态的由 PHP 变量传来的型别决定(string => SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 或 float/double=>SQLFLT8),在 oci8,$type 可以被设成 OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) 及 OCI_B_ROWID (ROWID)。如果要传入空值,使用 $db->Parameter($stmt, $null=null, 'param')。

最后,在 oci8,结合参数可以重复被使用,而无需再一次呼叫 PrepareSP() 或 Parameters。但这对 mssql 是不行的。一个 oci8 的范例如下:

$id = 0; $i = 0;
$stmt = $db->PrepareSP( "update table set val=:i where id=:id");
$db->Parameter($stmt,$id,'id');
$db->Parameter($stmt,$i, 'i');
for ($cnt=0; $cnt < 1000; $cnt++) {
        $id = $cnt;
        $i = $cnt * $cnt; # oci8 下可以运作
        $db->Execute($stmt);
}
Bind($stmt, $var, $size=4001, $type=false, $name=false)

这是一个低阶函数,只有 oci8 驱动程序支持。只有你确定系统仅支持 Oracle 否则请避免使用它。Parameter() 函数是使用结合变量的另一个建议方式。

Bind() 允许你使用结合变量在你的 sql 叙述中。这里结合一个PHP变量给一个在之前被 Prepare() 预先编译的 Oracle sql 叙述里定义的名称。Oracle 以一个冒号为开头来命名一个变量,而且 ADODB 需要一个被命名的变量去对应 :0,:1,:2,:3,等等。第一次被 Bind() 取得的将会代入 :0,而第二次将会代入 :1,依此类推。对 insert , select 及 update 指令,结合可以提供 100% 的效能提升。

在其余的参数里,$size 设定资料储存的暂存区大小,$type 是 OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) 及 OCI_B_ROWID (ROWID) 的类别选项。最后,代替使用预设的 :0,:1 等等名称,你可以使用 $name 来定义你自己的连结名称。

接下来的例子展示3个连结变量,使用 p1,p2及p3来结合。这些变量将会配到 :0 , :1 及 :2 。

$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
$DB->Bind($stmt, $p1);
$DB->Bind($stmt, $p2);
$DB->Bind($stmt, $p3);
for ($i = 0; $i < $max; $i++) {
   $p1 = ?; $p2 = ?; $p3 = ?;
   $DB->Execute($stmt);
}
你也可以使用名称变量:

$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:name0, :name1, :name2)");
$DB->Bind($stmt, $p1, "name0");
$DB->Bind($stmt, $p2, "name1");
$DB->Bind($stmt, $p3, "name2");
for ($i = 0; $i < $max; $i++) {
   $p1 = ?; $p2 = ?; $p3 = ?;
   $DB->Execute($stmt);
}

PHP中 ADOdb 类库应用(三):参考手册(1)

[]包起来的参数为选用参数,可有可无。

共享变量

$ADODB_COUNTRECS

当本变量($ADODB_COUNTRECS)被设为 true 时,如果数据库驱动程序接口(API)不支持回传被 SELECT 指令所选取的数据笔数,那么 RecordCount() 函数将会自动仿真,并回传正确的数据笔数,默认值即为 true。仿真方式是建立一个内存暂存区来放置这些资料,因此当取回的资料笔数很大时,会占用很大量的内存。当设定本变量值为 false 时,会有最好的效能。本变量在每次执行查讯时都会自动检查,所以你可以依实际需要在每次查询前进行设定。

$ADODB_CACHE_DIR

如果你使用了资料集快取功能,那么那些快取资料都会被置放到这个变量所指定的目录里。所以当你要使用诸如 CacheExecute() 函数前,你应该要先设定好本变量。期于安全的考量,如果你要使用 $ADODB_CACHE_DIR,我们建议你将在 php.ini 里的 register_globals 设成 off

$ADODB_FETCH_MODE

这个共享变量决定了资料集以那种方式将资料传给数组。数据集在被建立时( Execute()SelectLimit())会把本变量($ADODB_FETCH_MODE)的值保存下来,而随后本变量($ADODB_FETCH_MODE)的任何改变都不会影响到现存的资料集,只有在以后资料集被建立起来时才会改变。

以下为为已定义的常数:

define('ADODB_FETCH_DEFAULT',0);
define('ADODB_FETCH_NUM',1);
define('ADODB_FETCH_ASSOC',2);
define('ADODB_FETCH_BOTH',3);

以下为一个使用的例子:

        $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); # 显示 array([0]=>'v0',[1] =>'v1')
         print_r($rs2->fields); # 显示 array(['col1']=>'v0',['col2'] =>'v1')

在本范例中,如你所见两个数据集在被Execute()建立时,会依据 $ADODB_FERCH_MODE 的值来决定储存及使用的存取模式。

如果没有任何的模式被设定,默认值则是 ADODB_FETCH_DEFAULT。呈现的模式则依据数据库驱动程序而有所不同。为了可移植性,我们建议你固定为 ADODB_FETCH_NUM ADODB_FETCH_ASSOC,因为有许多驱动程序并不支持 ADODB_FETCH_BOTH

ADOConnection

提供连结数据库,执行SQL指令以及一组准格式化的SQL相关函数等功能的对象。

ADOConnection 属性

databaseType: 要连结的数据库系统名称,如 odbc,mssql,mysql…等。详细内容请参考上表。

dataProvider: 下层的数据库结结机制,除了使用 odbc ado 外,一般正常会设为 native

host: 数据库主机名称,可用IP或来源名称(DSN)进行连结。如203.74.225.22 , dbs1.nukepro.com , "localhost" , "odbc_dsn1"

database: 数据库或连结名称,如果使用了 ado,则会控制 ado 资料提供驱动程序(ado data provider)

user: 登入时的 ID,密码则基于安全考量没有保留。

raiseErrorFn: 允许你定义一个错误处理函数,请参考 ADOdb-errorhandler.inc.php 的范例.

debug: 被设定为 true 时,会显示除错讯息。

concat_operator: 连结操作数,一般会设为 '+' '||'。这个操作数是为了在 SQL 里连结字符串的。会在 Concat 函数中被用到。

fmtDate: 日期格式,在DBDate函数中会使用到,做为送日期资料到数据库的依据。在Access格式为'#Y-m-d#',在MySQL格式为"\Y-m-d\"

fmtTimeStamp: 时间格式,在 DBTimeStamp 函数中要送时间资料到数据库时会使用到。

true: 资料中真值的表现方式,如在Foxpro'T'MS SQL'1'

false: 资料中假值的表现方式,如在Foxpro'F'MS SQL'0'

replaceQuote: 这个字符串用来处理逸出符号。例如在 Microsoft SQL 里的双引号,MySQL里的反斜线符号。主要使用于 qstr

autoCommit: 设定是否激活自动交易模式,默认值为 true

charSet: 设定使用的字符集,目前只有 interbase 支持。

metaTablesSQL: 使用SQL指令,以回传一份可用的数据表清单。例如在 MySQL 里的 SHOW TABLES

genID: 如果数据库有支持的话,这里会存放由GetID()所取得的最后值。

cacheSecs: 快取资料集的秒数。用于当使用者利用 CacheExecute() CacheSeletLimit() 函数,又没有设定 $secs2cache 参数时的默认值。

sysDate: 利用数据库函数去取得目前的日期和时间。会使用到原生的日期时间标记格式。

PHP中 ADOdb 类库应用(二)

4   ADODB的查询方法

ADODB的查询方法如下。
4.1.直接查询

Excute()方法通过连接句柄执行SQL查询,并返回一个变量,如下:

$sql='SELECT * FROM ice_cream WHERE flavor LIKE ?';
$res = $cnx->Execute($sqlarray('Chocolate'));

4.2.缓存查询

ADODB提供内置的缓存机制,CacheExecute()方法用于每次查询数据时,会把相应的结果序列化后保存到文件中,以后同样的查询语句就可以不用直接查询数据库,而是从缓存文件中获取,从而提高Web系统的性能。CacheExecute()方法的格式如下

CacheExecute($ttc$sql)
该方法以缓存的形式执行一段查询,其中$ttc为缓存的时间,请看如下代码:

$ADODB_CACHE_DIR = "/var/tmp/adodb_cache"; //缓存保存的文件目录
$sql = "SELECT surname, age FROM employees"; //构造一个查询
$rs = &$db->CacheExecute(600,$sql);
//
缓存式查询,缓存将被保存600秒后更新

4.3.清除缓存CacheFlush()

该方法用来清除所有ADODB数据库的缓存。  

5、移动记录集

记录集(Record Set):从执行的方法中返回指定的记录,使用moveFirst()moveLast()moveNext()move($n)方法访问记录集中的一个指定记录。例如:

$rs=$cnx-&gt;Execute('SELECT flavor,price FROM ice_cream');
$rs-&gt;MoveLast
();
print
"Flavor ".$rs-&gt;fields[0].
" costs "
.$rs-&gt;fields[2]."\n"
;
$rs-&gt;MoveFirst
();
//省略...
$rs-&gt;Move(2
);
//省略...
$rs-&gt;MoveNext();

 

设置一个全局变量$ADODB_FETCH_MODE,从ADODB_FETCH_NUM(或从ADODB_FETCH_ASSOC返回)中取得数字索引(或关联索引)数组。例如:

 

$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs=$cnx-&gt;Execute('SELECT flavor,price FROM ice_cream'
);
print
"&lt;table&gt;\n"
;
while (!
$rs-&gt;EOF
) {
    print
"&lt;tr&gt;&lt;td&gt;".$rs-&gt;fields['flavor']}."&lt;/td&gt;"
.
   
"&lt;td&gt;".$rs-&gt;fields['price']"."&lt;/td&gt;&lt;/tr&gt;n
";
    $rs-&gt;MoveNext();
}
print "
&lt;/table&gt;n";

FetchObject()方法也是一个记录集变量。

6 、使用ADODB生成HTML

ADODBrs2html($res)函数,它提供一个简单的方法,从$res变量中的记录自动生成HTML表格。

它在tohtml.inc.php中,使用时需要包含进来,如下代码:

require 'adodb/tohtml.inc.php';
//
引入rs2html函数

require 'adodb/adodb.inc.php';
//省略...
$rs = $cnx->Execute('SELECT flavorcaloriesprice FROM ice_cream');
rs2html($rs);
使用rs2html($res'CLASS="myClass")这种格式,表示指定表格使用的myClass的样式表类进行显示。

7 、使用ADODB进行分页

ADODB_Pager(该方法定义在adodb-pager.inc.php中)提供一种简单分页显示记录的方法。
require 'adodb/adodb.inc.php';
require 'adodb/adodb-pager.inc.php';
$pager=new ADODB_Pager($cnx"SELECT idflavorprice FROM ice_cream_big");
$pager->Render();
使用$pager->Render($num)来设置每次显示的行数,默认值为10

 

8、生成下拉选择菜单

getMenu($selectName)方法将帮助我们生成一个<select>标签,即从记录集中生成一个下拉菜单。其中,$selectName是该表单中selectname标签。例如:
$rs = $cnx->execute('SELECT flavorid FROM ice_cream');
print $rs->GetMenu('which_flavor');
相关说明如下:
ØgetMenu($sN$selected$blank$mult$nm):其中,$selected (string)为默认选择的值/项。
Ø$blank (boolean):默认初始值或布尔值为true时,下拉选项为空。
Ø$mult (boolean):下拉菜单是否可以允许多选。
Ø$nm (integer):设置菜单多重选择的属性,也就是默认几行。

PHP中 ADOdb 类库应用(一)

下载ADODB:可以在http://adodb.sourceforge.net/ 取得最新版的ADODBA。DODB的最新版本是adodb495a版,根据需要,可以下载完整版本的ADODB。如果您主要使用MySQL,则可以下载ADODBlite版本,减少体积和一些不必要的系统开销。

1、使用ADODB

由于PHP的数据库存取函数没有标准化,所以需要一组函数库或类别来隐藏不同数据库函数界面间的差异。可以实现相对简单的数据库系统移植,这就是ADODB抽象层要实现的目标。

ADODB目前支持的数据库系统MySQLOracleMS SQL ServerSybase/Sybase SQL AnywhereInformixPostgreSQLFrontBaseInterbaseFirebirdBorland版本)、FoxproAccessADOODBC连接。
与其他数据库抽象层相比,其他类大多集中在处理与SELECT操作有关的内容,而ADODB对于INSERTUPDATE操作也提供额外的支持,并且可以很快连接到多类数据库,提供的统计方法,在底层实现字串连接及字串标记变量的差异处理(在某些数据库中,字串的连接和标记符号是有差异的)。

字段类型对照系统是ADODB抽象层的特性之一,所以我们可以描述像CHARTEXT(而OracleClob类型)及STRING这样的通用字段类型,而不必理会采用的数据库使用的是哪种类型,它会在底层替我们做对应和转换。
因此使用ADODB开发,对于系统来说移植相对变得容易,因为所有与数据库相依存的程序代码被都隐藏在后端,使用者不再需要去移植类别里的逻辑。

 

2、安装

首先要确定你所使用的PHP版本是 4.01pl2 或是之后的版本(因为ADODB使用到了 require_onceinclude_once两个函数)。解压缩全部的档案到你的Web服务器可以存取的一个目录里。

要测试ADODB你需要一个数据库,开启 testdatabase.inc.php 这个档案,并且修改连结参数,以适合你所使用的数据库。这个程序会建立一个新的资料表在你的数据库中,以支持我们提供的测试程序及范例。

就这样,你安装好了。

3、激活ADODB

当要执行ADODB时,至少有两个档案要被载进来,第一个是 ADOdb.inc.php ,这里面包含了所有数据库类中要被使用的函数。而对数据库实作的程序代码则被置放在ADOdb-????.inc.php档案里。

例如说,要连结一个mysql数据库:

include('/path/to/set/here/ADOdb.inc.php');
$conn = &ADONewConnection('mysql');

无论何时你需要连结到一个数据库时,你必需使用ADONewConnection()函数建立了一个连结对象。ADONewConnection接受一个选择性参数, <database-name-here>。如果没有参数被指定,它将会使用被 ADOLoadCode() 所加载的最后一个数据库。 NewADOConnection() 是另一个相同的函数。

当你建立好一个连结对象时,你并没有真的连结上你的数据库。你仍需要使用 $conn-&gt;Connect() 或者 $conn-&gt;PConnect() 两个方法来完成真正的连结。

你可以参考教学手册里的范例,对上面的说明做更深入的了解。