虽然PHP是建构Web系统强有力的工具,但是PHP存取数据库的功能,一直未能标准化,每一种数据库,都使用另一种不同且不兼容的应用程序接口(API)。为了填补这个缺憾,因此才有ADODB的出现。一旦存取数据库的接口予以标准化,就能隐藏各种数据库的差异,若欲转换至其它不同的数据库,将变得十分容易。 目前ADODB支持的数据库种类非常地多,例如:MysqL,Postgresql,Interbase,Informix,Oracle,MSsql7,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','test'); //设定sql命令 $sql="insertintotvalues('abcde',18)"; //执行sql命令 $rs=$conn->Execute($sql); //检查执行结果,若$rs==false,则呼叫$conn对象的成员函式ErrorMsg() if(!$rs)print$conn->ErrorMsg();elseprint"OK!"; ?> 结果如下: --------------------------------------------- (MysqL):insertintotvalues("abcde",18) --------------------------------------------- OK! 若把侦错关掉,即$conn->debug=false,则结果如下: OK! 以下,逐步为各位介绍:使用ADODB的重点方法。 2.安装
ADODB的首页在:http://PHP.weblogs.com/ADOdb,目前(2002/10/24)最新版是:2.42版,可至ADODB下载或至台南县教网中心FTP下载。 安装ADODB的方法超极简单,只要下载、解压、放入适当位置,即可完成!如下所示: 1.下载: $ncftpftp.tnc.edu.tw cdsysop/ADODB getadodb242.tgz 2.解压: 假设我把adodb242.tgz放入/var/www/html中 $cpadodb242.tgz/var/www/html $tarxvzfadodb242.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的PEARDB语法来使用ADODB。此时,尚可使用DSN连接数据库的字符串设定。如$dsn="MysqL://piza:ooo123@localhost/test"; 若是引入tohtml.inc.PHP,可帮您在程序代码中,方便将取出的记录,转成HTML的表格(table)来显示。 若是引入toexport.inc.PHP,可让您方便地输出CSV档或以tab分隔字段的数据文件。 若是引入rsfilter.inc.PHP,可让您在使用记录之前,预做过滤处理。 若是引入pivottable.inc.PHP,可让您使用pivottable功能(俗称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(DataSourceNames)相关数据,DSN可能包括:主机名称、数据库使用者、数据库密码、数据库名称。不同的数据库种类,DSN可能可以省略其中若干项。以MysqL而言,则上述四者都要提供。 该函式会传回true或false,用以表示是否连接成功。 用例: //格式:$conn->Connect('主机','数据库'); $conn->Connect('localhost','test'); 或者,采持续性连接: //格式:$conn->PConnect('主机','数据库'); $conn->PConnect('localhost','test'); 若欲探查是否有联机成功,可用一个变量来接取传回值: $mch="localhost"; $user="piza"; $pwd="ooo123"; $database="test"; $cok=$conn->Connect($mch,$user,$pwd,$database); 或者,采持续性连接: $cok=$conn->PConnect($mch,$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="INSERTINTOtVALUES('$name',$year)"; //$sql="insertintotvalues('$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,$database); //产生一笔空记录 $sql="selectfromtwhereyear=-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):selectfromtwhereyear=-1 ----------------------------------------------------------- (MysqL):INSERTINTOt(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,$database); //执行Select由表格t取出数据, //它会传回一个ADORecordSet记录集对象$rs(RecordSet) //实际上$rs是一个cursor指标,它拥有目前的记录(row或称record), //该记录的所有字段数据的内容,存放在fields这个数组之中 //,以数字为索引,第一个由0开始 $rs=&$conn->Execute('selectfromt'); //若$rs为false,则秀出错误讯息 if(!$rs){ print$conn->ErrorMsg(); }else{ //当尚未到达记录集$rs的结束位置(EOF:EndOfFile)时,(即:还有记录尚未取出时) while(!$rs->EOF){ //秀出所有字段,$FieldCount()会传回字段总数 for($i=0,$max=$rs->FieldCount();$i<$max;$i++){ print$rs->fields[$i].""; } //移至下一笔记录 $rs->MoveNext(); //换列 echo"
\n"; } } $rs->Close();//可不用 $conn->Close();//可不用 ?> $rs->fields[]数组是由PHP的数据库扩展功能产生的,某些扩展功能并不支持使用字段名称当作索引。 若欲使用名称当作索引,也就是俗称的hash或associativearrays,则需使用全域变量$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,$database); //执行sql之前,指定使用名称索引 $ADODB_FETCH_MODE=ADODB_FETCH_ASSOC; //执行Select,它会传回一个ADORecordSet记录集对象$rs //实际上$rs是一个cursor指标,它拥有目前的记录内容, //该记录存放在fields这个数组之中 $rs=&$conn->Execute('selectfromt'); //若$rs为false,则秀出错误讯息 if(!$rs){ print$conn->ErrorMsg(); }else{ //当尚未到达记录集结束位置(EOF)时, while(!$rs->EOF){ //秀出所有字段 print$rs->fields['name']."".$rs->fields['year']; //移至下一笔记录 $rs->MoveNext(); //换列 echo"
\n"; } } $rs->Close();//可不用 $conn->Close();//可不用 ?> 10.取出记录(使用FetchRow)
这里示范FetchRow的用法: $sql="selectfromt"; $rs=$conn->Execute($sql); if($rs){ while($ar=$rs->FetchRow()){ print$ar['name']."".$ar['year']; print"
\n"; } } FetchRow()会将取出的记录传回,您可用一个array来接取。 注意!使用FetchRow()就不必再用MoveNext(),FetchRow内部会自动完成移至下一笔记录的动作。 11.更新记录(Update)
您可以用传统的方式: $sql="UPDATEtSETname='john',year=28WHEREyear=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,$database); //选择要更新的那一笔记录 $sql="selectfromtwhereyear=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):selectfromtwhereyear=18 ------------------------------------------------------------- (MysqL):UPDATEtSETname='john',year=28WHEREyear=18 ------------------------------------------------------------- 12.删除记录(Delete)
删除记录很简单,采传统方式即可:$sql="DELETEFROMtWHEREyear=18"; $rs=$conn->Execute($sql); 13.使用字段对象(FieldObjects)
这里示范字段对象FetchField的用法,用以取得字段名称及字段型态: $sql="selectfromt"; $rs=&$conn->Execute($sql); if($rs){ while(!$rs->EOF){ //取出第二个字段 $f=$rs->FetchField(1); //印出字段名称及字段型态 print$f->name.":".$f->type; $rs->MoveNext(); print"
\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,$database); $sql="selectfromt"; //产生pager对象 $pager=newADODB_Pager($db,$sql); //每一页秀5笔记录 $pager->Render($rows_per_page=5); ?> 结果如下: Figure1.简单分页功能 每页显示记录的数目是由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,$database); $sql="selectnameas'姓名',yearas'年纪'fromt"; //产生pager对象 $pager=newADODB_Pager($db,$sql); //每一页秀5笔记录 $pager->Render($rows_per_page=5); ?> 结果如下: Figure2.改变字段名称 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,yearas'年纪'fromt"; $rs=$db->Execute($sql); //秀出CSV格式 printrs2csv($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方法如下: printrs2tab($rs,false); 注:false表示不显示字段名称 结果如下: abcde45 yyy20 ppp34 mmm13 hhh41 rrr65 kkk29 miso154 sss89 abc18 abcde0 uyt58 john28 若是printrs2tab($rs,true); 结果如下: 姓名年纪 abcde45 yyy20 ppp34 mmm13 hhh41 rrr65 kkk29 miso154 sss89 abc18 abcde0 uyt58 john28 也可以将结果由标准输出(STDOUT)显示,使用rs2tabout方法如下: printrs2tabout($rs); 执行结果如下: Figure1.在console中显示结果 也可以存成CSV档: //档案路径 $path="/tmp/test.csv"; //开档供写入 $fhd=fopen($path,"w"); //若开档成功 if($fhd){ //则写入CSV rs2csvfile($rs,$fhd); //也可以使用rs2tabfile($rs,$fhd); //关档 fclose($fhd); } 结果如下: [ols3@pweb]$cat/tmp/test.csv 姓名,28 16.取出一定笔数的记录(使用SelectLimit)
ADODB提供一个ADOConnect函式SelectLimit,可供您取出一定笔数的记录,用法如下: $conn->Connect($mch,$database); rs=$conn->SelectLimit("Selectfromt",3,1); //取出3笔、在第1笔之后 //秀出这3笔记录 if($rs){ while($ar=$rs->FetchRow()){ print$ar['name']."".$ar['year']; print"
\n"; } } 上式是说:在第1笔记录之后,取出3笔,也就是第2、3、4笔记录。 结果如下:
-------------------------------------- (MysqL):select*fromtLIMIT1,3 -------------------------------------- 注意!SelectLimit的写法刚好和MysqL语法相反!