您的位置:首页 > 其它

Pear DB 新手入门指南

2008-11-21 13:52 302 查看
1.简介
这是一部指导我们如何使用PearDB扩展。PearDB,提供这样一系列的类:
n数据库抽象
n高级错误处理机制
n以及其它

2.下载、安装Pear
由于现在Pear项目仍处于紧锣密鼓的开发之中,所以得到它的最好办法就是从CVS获得(PearDB发行包已经跟随PHP4.0.6以后版本捆绑发布)。所以,我们只需要把Pear的根目录放到php.ini配置文件include_path中。也可以通过这样设置:_set('include_path','/pear_base_dir').
以下是strpbystep示例:
存放Pear的目录:
#cd/usr/local/lib
用“phpfi“口令登录:
#cvs-d:pserver:cvsread@cvs.php.net:/repositorylogin
用以下命令得到所有的pear文件,同时也可以用来更新已经下载的文件。其他的参数有:"today","lastmonth",等。我推荐用"lastweek"参数,因为一般bugs的提交和修改都是每周一次。
#cvs-d:pserver:cvsread@cvs.php.net:/repositoryexport-D"lastweek"php4/pear
编辑php.ini文件加上下面一段在include_path处:/usr/local/lib/php4/pear如果没有修改的权限,可以通过这条语句在代码中实现:ini_set('include_path','path_to_pear');
获得PHPCVS的完全文档
注意PearDB必需PHP版本4.0.4以上,而在Pear中的一些其他包如:XMLParserofthepearinstallerscript需要PHP4.0.5以上版本。

3.使用PearDB
3.1连接,断开数据库
<?php

//Thepearbasedirectorymustbeinyourinclude_path

require_once
'DB.php'
;

$user
=
'foo'
;

$pass
=
'bar'
;

$host
=
'localhost'
;

$db_name
=
'clients_db'
;


//DataSourceName:Thisistheuniversalconnectionstring

$dsn
=
"mysql://$user:$pass@$host/$db_name"
;


//DB::connectwillreturnaPearDBobjectonsuccess

//oraPearDBErrorobjectonerror

//YoucanalsosettoTRUEthesecondparam

//ifyouwantapersistentconnection:

//$db=DB::connect($dsn,true);

$db
=
DB
::
connect
(
$dsn
);


//WithDB::isErroryoucandifferentiatebetweenanerroror

//avalidconnection.

if(
DB
::
isError
(
$db
)){

die(
$db
->
getMessage
());

}

....

//Youcandisconnectfromthedatabasewith:

$db
->
disconnect
();

?>
数据源(上例中的$dsn参数)有以下允许的格式:(从Pear/DB.php的parseDSN方法复制而来)

*phptype:DatabasebackendusedinPHP(mysql,odbcetc.)

*dbsyntax:DatabaseusedwithregardstoSQLsyntaxetc.

*protocol:Communicationprotocoltouse(tcp,unixetc.)

*hostspec:Hostspecification(hostname[:port])

*database:DatabasetouseontheDBMSserver

*username:Usernameforlogin

*password:Passwordforlogin

*

*TheformatofthesuppliedDSNisinitsfullestform:

*

*phptype(dbsyntax)://username:password@protocol+hostspec/database

*

*Mostvariationsareallowed:

*

*phptype://username:password@protocol+hostspec:110//usr/db_file.db

*phptype://username:password@hostspec/database_name

*phptype://username:password@hostspec

*phptype://username@hostspec

*phptype://hostspec/database

*phptype://hostspec

*phptype(dbsyntax)

*phptype
现在支持的数据库有(在phptypeDSN部分):

mysql->MySQL

pgsql->PostgreSQL

ibase->InterBase

msql->MiniSQL

mssql->MicrosoftSQLServer

oci8->Oracle7/8/8i

odbc->ODBC(OpenDatabaseConnectivity)

sybase->SyBase

ifx->Informix

fbsql->FrontBase
注意并不是所有数据库特征都支持,可以从根目录>/DB/STATUS得到详细的清单。

3.2执行数据库
<?php

//OnceyouhaveavalidDBobject

...

$sql
=
"select*fromclients"
;

//Ifthequeryisa"SELECT",$db->querywillreturn

//aDBResultobjectonsuccess.

//ElseitsimplywillreturnaDB_OK

//OnfailureitwillreturnaDBErrorobject.

$result
=
$db
->
query
(
$sql
);

//Alwayscheckthat$resultisnotanerror

if(
DB
::
isError
(
$result
)){

die(
$result
->
getMessage
());

}

....

?>
3.3获得select的数据
3.3.1获取数据的函数
<?php

//OnceyouhaveavalidDBResultobject

...

//Geteachrowofdataoneachiterationuntil

//thereisnomorerows

while(
$row
=
$result
->
fetchRow
()){

$id
=
$row
[
0
];

}

?>
除了fetchRow()还可以使用fetchInto()直接插入$row的值。

<?php

...

while(
$result
->
fetchInto
(
$row
)){

$id
=
$row
[
0
];

}

?>
3.3.2选择获取数据的格式
获取模式有DB_FETCHMODE_ORDERED(默认),DB_FETCHMODE_ASSOCandDB_FETCHMODE_OBJECT.

从获取数据方法返回的结果示例:
<?php

$res
=
$db
->
query
(
'selectid,name,emailfromusers'
);

$row
=
$res
->
fetchRow
(
$mode
);


//With$mode=DB_FETCHMODE_ORDERED

//Thedefaultbehavioristoreturnanorderedarray.

$row
=array(

0
=><
column
"id"
data
>,

1
=><
column
"name"
data
>,

2
=><
column
"email"
data
>

);


$id
=
$row
[
0
];


//With$mode=DB_FETCHMODE_ASSOC

//Returnsanassociativearraywithcolumnnamesasarraykeys:

$row
=array(

'id'
=><
column
"id"
data
>,

'name'
=><
column
"name"
data
>,

'email'
=><
column
"email"
data
>

);


$id
=
$row
[
'id'
];


//With$mode=DB_FETCHMODE_OBJECT

//ReturnsaDB_rowobjectwithcolumnnamesasproperties:

$row
=
db_rowObject

(

[
id
]=><
column
"id"
data
>,

[
name
]=><
column
"name"
data
>,

[
email
]=><
column
"email"
data
>

)


$id
=
$row
->
id
;

?>
3.3.3设置获取数据的格式
可以使用fetchrow()/fetchInto()方法或者为你的DB实例设置一个默认的模式。

<?php

...

//1)Setthemodepercall:

while(
$row
=
$result
->
fetchRow
(
DB_FETCHMODE_ASSOC
)){

[..]

}

while(
$result
->
fetchInto
(
$row
,
DB_FETCHMODE_ASSOC
)){

[..]

}


//2)Setthemodeforallcalls:

$db
=
DB
::
connect
(
$dsn
);

//thiswillsetadefaultfetchmodeforthisPearDBinstance

//(forallqueries)

$db
->
setFetchMode
(
DB_FETCHMODE_ASSOC
);

$result
=
$db
->
query
(...);

while(
$row
=
$result
->
fetchRow
()){

$id
=
$row
[
'id'
];

}

?>
3.3.4控制获取数据数量
同时PearDB获取数据可以带有额外的参数,可以使用一个数字参数来获取需要的数据数量。在你只需要获得数据中的一部分时这时候特别有用(比如在做分页程序的时候)

<?php

...

//therowtostartfetching

$from
=
50
;

//howmanyresultsperpage

$res_per_page
=
10
;

//thelastrowtofetchforthispage

$to
=
$from
+
$res_per_page
;

foreach(
range
(
$from
,
$to
)as
$rownum
){

if(!
$row
=
$res
->
fetchrow
(
$fetchmode
,
$rownum
)){

break;

}

$id
=
$row
[
0
];

....

}

?>
3.3.5清除结果,释放变量
当你完成查询的时候,可以用free()方法来结束:

<?php

...

$result
=
$db
->
query
(
'SELECT*FROMclients'
);

while(
$row
=
$result
->
fetchRow
()){

...

}

$result
->
free
();

?>
3.4快速retrieve数据
当你不再想用fetchRow()方法来获取数据的时候,PearDB通过sql语句提供一些特别的方法来返回想要的数据。这些方法有:getOne,getRow,getCol,getAssocandgetAll.这有一些使用示例:

<?php

require_once
'DB.php'
;

$db
=
DB
::
connect
(
'pgsql://postgres@unix+localhost/clients_db'
);

//-----------------------------------------------------------

//getOneretrievesthefirstresultofthefirstcolumn

//fromaquery

$numrows
=
$db
->
getOne
(
'selectcount(id)fromclients'
);

//-----------------------------------------------------------

//getRowwillfetchthefirstrowandreturnitasanarray

$sql
=
'selectname,address,phonefromclientswhereid=1'
;

if(
is_array
(
$row
=
$db
->
getRow
(
$sql
))){

list(
$name
,
$address
,
$phone
)=
$row
;

}

//-----------------------------------------------------------

//getColwillreturnanarraywiththedataofthe

//selectedcolumn.Itacceptsthecolumnnumbertoretrieve

//asthesecondparam.

//Thenextsentencecouldreturnforexample:

//$all_client_names=array('Stig','Jon','Colin');

$all_client_names
=
$db
->
getCol
(
'selectnamefromclients'
);

//-----------------------------------------------------------

//Otherfunctionsare:getAssoc()andgetAll().

//Forthemomentrefertotheirin-linedocumentation

//atpear/DB/common.php

//-----------------------------------------------------------

?>
"get*()系列方法"可以为你做很多事情,包括:发起一个查询,获取数据和清除结果。请注意所有的PearDB函数将可能返回一个PearDB_error对象。

3.5从查询结果获得更多信息(numRows,numCols,affectedRows,tableInfo)
通过PearDB可以从查询结果获得更多有用的数据信息。这些方法有:

numRows():通过一个"SELECT"查询返回所有数据的数量。
numCols():通过一个"SELECT"查询返回所有的列。
affectedRows():通过("INSERT","UPDATE"or"DELETE")操作返回所有受影响的数据行数。
tableInfo():通过一个"SELECT"查询返回一个包含数据信息的数组。

示例:

<?php

...

$db
=
DB
::
connect
(
$dsn
);

$sql
=
'select*fromclients'
;

$res
=
$db
->
query
(
$sql
);

//Don'tforgettocheckifthereturnedresultfromyour

//actionisaPearErrorobject.Ifyougetaerrormessage

//like'DB_error:databasenotcapable',meansthat

//yourdatabasebackenddoesn'tsupportthisaction.

//

//Numberofrows

echo
$res
->
numRows
();

//Numberofcols

echo
$res
->
numCols
();

//TableInfo

print_r
(
$res
->
tableInfo
());

//Affectedrows

$sql
=
"deletefromclients"
;

//rememberthatthisstatementwon'treturnaresultobject

$db
->
query
(
$sql
);

echo
'Ihavedeleted'
.
$db
->
affectedRows
().
'clients'
;

?>
3.6自动增长(Sequences)
Sequences为数据行提供独一无二的ID标识。如果熟悉MySQL之类的话,可以把它想象为AUTO_INCREMENT.它非常简单,首先你获取一个ID,然后在这个ID所在的行插入你所需要记录的数据。可以为你的表设置更多的Sequences,只需要保证在任何特殊的表中都使用一样的sequence就行。

<?php

...

//GetanID(ifthesequencedoesn'texist,itwillbecreated)

$id
=
$db
->
nextID
(
'mySequence'
);


//UsetheIDinyourINSERTquery

$res
=
$db
->
query
(
"INSERTINTOmyTable(id,text)VALUES($id,'foo')"
);

...

?>
3.7Prepare&Execute/ExcuteMultiple
<?php

//UNTESTEDCODE!!!

//

//Exampleinsertingdata

$alldata
=array(

array(
1
,
'one'
,
'en'
),

array(
2
,
'two'
,
'to'
),

array(
3
,
'three'
,
'tre'
),

array(
4
,
'four'
,
'fire'
)

);

$sth
=
$dbh
->
prepare
(
"INSERTINTOnumbersVALUES(,,)"
);

foreach(
$alldata
as
$row
){

$dbh
->
execute
(
$sth
,
$row
);

}

//Here'sanexampleofafileplaceholder:

$myfile
=
"/tmp/image.jpg"
;

$sth
=
$dbh
->
prepare
(
'INSERTINTOimages(,&)'
);

$dbh
->
execute
(
$sth
,array(
"thisisme"
,
$myfile
));

//AfterIcommitabugfixthatIhaveonmylaptop,youcanuse

//parameterarraysinthegetXxxmethodstoo:

$ver
=
$dbh
->
getOne
(
"SELECTstableversionFROMpackagesWHEREname="
,

array(
$package
));

?>
3.8autoCommit,commitandrollback
<?php

//exampleshere

?>
4.可用方法列表
<?php

/*

*FromtheDB_(driver)objects

*/

//gettheobjectwith,ie:

$db
=
DB
::
connect
(
'mysql://user:pass@localhost/my_db'
);


//Setoptions

$db
->
setErrorHandling
();

$db
->
setFetchmode
();

//Information

$db
->
affectedRows
();

$db
->
tableInfo
();

//Databasemanipulation

$db
->
query
();

//Datafetch

$db
->
nextId
();

$db
->
getOne
();

$db
->
getRow
();

$db
->
getCol
();

$db
->
getAssoc
();

$db
->
getAll
();

//Placeholdersandexecuterelated

$db
->
quote
();

$db
->
prepare
();

$db
->
execute
();

$db
->
executeMultiple
();

//Transactions

$db
->
autoCommit
();

$db
->
commit
();

$db
->
rollback
();

//Disconnection

$db
->
disconnect
();


/*

*FromDB_resultobjects

*/

//gettheobjectwith,ie:

$res
=
$db
->
query
(
'select*fromfoo'
);


//Datafetch

$res
->
fetchRow
();

$res
->
fetchInto
();

//ResultInfo

$res
->
numCols
();

$res
->
numRows
();

$res
->
tableInfo
();

//Free

$res
->
free
();


/*

*FromDB_errorobjects

*/

//gettheobjectwith,ie:

$error
=
$db
->
query
(
'select*fromno_table'
);


$error
->
getMessage
();

$error
->
getDebugInfo
();

$error
->
toString
();

?>
5.错误处理机制
5.1.从PearDBError获得错误信息
所有从PearDB返回的错误都是PearErrors.这有一种方法来搜集:

<?php

...

$res
=
$db
->
query
(
'select*fromno_table'
);

if(
DB
::
isError
(
$res
)){

//gettheportableerrorstring

echo
$res
->
getMessage
();

}

?>
4.2DebugPearDBErrors
PearDB采用一种轻便的错误消息系统向用户报错。把错误信息简单翻译成其它语言或者对于一种特殊错误采取特殊的处理方式这都带来了很大的优点。但是对于开发人员来说这些提示并么有提供很有用的信息。想要得到真实的数据处理出错的信息,你可以使用getDebugInfo()方法:

<?php

$sql
=
'select*fromno_table'
;

if(
DB
::
isError
(
$res
=
$db
->
query
(
$sql
))){

//getthenativebackenderror

//andthelastquery

echo
$res
->
getDebugInfo
();

}

?>
通过当一个PHP函数出错时,会打印出出错提示。在pear中的这种机制被屏蔽了。但时有时你可能需要在代码中捕捉一些错误信息。可以使用set_error_handlerPHP函数,从PHPManual获取信息.简单示例:

<?php

//whatmessagestoreport

error_reporting
(
E_ALL
^
E_NOTICE
);

//thisfunctionwillhandleallreportederrors

function
my_error_handler
(
$errno
,
$errstr
,
$errfile
,
$errline
){

echo
"In$errfile,line:$errline
/n
$errstr"
;

}

set_error_handler
(
'my_error_handler'
);

$db
=
DB
::
connect
(
'pgsql://postgres@localhost/no_db'
);

...

?>
5.3对错误采取自动处理
正如你所看见的,PearDB提供了广泛的错误检测和报告机制,这强迫开发人员必需对返回的数据结果进行检查,是否有错。PearDB同时照顾我们避免这种痛苦的工作,提供了一种灵活的体系,在一个错误出现的时候自动调用相应的措施。

这些可能的措施包括:

返回错误对象(PEAR_ERROR_RETURN).这是默认的.
打印错误(PEAR_ERROR_PRINT)
打印错误信息并忽略执行(PEAR_ERROR_DIE)
用PHP函数trigger_error()来列举错误(PEAR_ERROR_TRIGGER)
把错误对象传递给一个函数或者类的方法(PEAR_ERROR_CALLBACK)

简单示例:

<?php

require_once
'DB.php'
;

//Setthedefaultactiontotakeonerror

PEAR
::
setErrorHandling
(
PEAR_ERROR_DIE
);

//Fromhereyoudon'tneedtocheckerrorsanymore

$db
=
DB
::
connect
(
'pgsql://postgres@localhost/my_database'
);

$res
=
$db
->
query
(
'selectidfromno_table'
);

//atthispointtheexecutionisabortedandtheerrormessageisraisen

...

?>
高级示例:

<?php

//Definetheappenvironment(thisis:whaterrorsyouwanttooutput)

define
(
'DEBUG_ENV'
,
true
);

//Thisfunctionwillhandleallerrors

function
handle_pear_error
(
$error_obj
){

//Beverbosewhiledevelopingtheapplication

if(
DEBUG_ENV
){

die(
$error_obj
->
getMessage
().
"/n"
.
$error_obj
->
getDebugInfo
());

//Dumpasillymessageifthesiteisinproduction

}else{

die(
'Sorryyourequestcannotbeprocessednow.Tryagainlater'
);

}

}


require_once
'DB.php'
;

//Onerror,callthe"handle_pear_error"functionback

//Youcanalsouseanobjectaspearerrorhandlerso:

//setErrorHandling(PEAR_ERROR_CALLBACK,array($object,'method_name');

PEAR
::
setErrorHandling
(
PEAR_ERROR_CALLBACK
,
'handle_pear_error'
);

$db
=
DB
::
connect
(
'pgsql://postgres@localhost/site_db'
);

$res
=
$db
->
query
(
'selectidfromno_table'
);

//atthispointtheexecutionisabortedandthe"handle_pear_error"

//functioniscalledwiththeerrorobjectasitsfirstargument

while(
$row
=
$res
->
fetchRow
()){

...

}

...

?>
下面为扩展错误机制提供了一个很好的想法:

<?php

error_reporting
(
E_ALL
^
E_NOTICE
);

//thisfunctionwillhandleallerrorsreportedbyPHP

function
php_error_handler
(
$errno
,
$errstr
,
$errfile
,
$errline
){

die(
"In$errfile,line:$errline
/n
$errstr"
);

}

set_error_handler
(
'php_error_handler'
);

//thisfunctionwillcatcherrorsgeneratedbyPear,

//transformittoPHPerrorsandtriggerthemtothephp_error_handler

function
pear_error_handler
(
$err_obj
){

$error_string
=
$err_obj
->
getMessage
().
'
'
.
$error_obj
->
getDebugInfo
();

trigger_error
(
$error_string
,
E_USER_ERROR
);

}

require
'DB.php'
;

PEAR
::
setErrorHandling
(
PEAR_ERROR_CALLBACK
,
'pear_error_handler'
);

//forceanerror

$db
=
DB
::
connect
(
'pgsql://postgres@localhost/no_db'
);

...

?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: