• 3894阅读
  • 0回复

php数据对象 PDO使用简介 [复制链接]

上一主题 下一主题
离线cai
 

只看楼主 倒序阅读 0楼 发表于: 2005-12-25
作者: mzt
出自: http://www.phpchina.cn

PHP 5.1 发布时附带一个全新的数据库连接层,即 PHP Data Objects (PDO)。它与ADODB和Pear DB等数据库抽象层不同,它提供的是如何存取数据库和处理查询结果,效率也更高,还可以通过预处理语句来防止sql注入。

目前支持的数据库有:

• DBLIB: FreeTDS / Microsoft SQL Server / Sybase
• Firebird (http://firebird.sourceforge.net/): Firebird/Interbase 6
• MYSQL (http://www.mysql.com/): MySQL 3.x/4.x
• OCI (http://www.oracle.com): Oracle Call Interface
• ODBC: ODBC v3 (IBM DB2 and unixODBC)
• PGSQL (http://www.postgresql.org/): PostgreSQL
• SQLITE (http://www.postgresql.org/): SQLite 3 and SQLite 2

1. 连接数据库

通常我们连接数据库使用的是不同的连接函数(如:mysql_connect,pg_connect),PDO提供了统一的接口:PDO对象。

$db = new PDO(
"pgsql:dbname=pdo;host=localhost",
"postgres8",
"postgres8"
);
echo "Successfully created a PDO object";
?>

就像你看到的,PDO有三个参数,
• 连接字符串
pgsql 是使用的PDO驱动,可以为:mysql, mssql, sybase, dblib, firebird, oci, odbc, pgsql, sqlite, sqlite2;
dbname 是数据库名称,这里假设有一个名为pdo的测试数据库;
host 是指要连接到哪里,如果是本地则为localhost。
• 用户名
• 密码

做这一步之前,请先确认已经加载了PDO模块。如果我们试图处理一个无效的连接字符串:

$db = new PDO(
"THIS_IS_NOT_A_PDO_MODULE:dbname=pdo;host=localhost",
"foo",
"bar"
);
echo "Successfully created a PDO object";
?>

PHP将会返回以下错误:

Fatal error: Uncaught exception 'PDOException' with message 'could not find driver'

所以,我们可以用一种优雅的方式来处理,即抛出PDO异常来处理错误(但并不是所有情况都是)。

try
{
$db = new PDO(
"THIS_IS_NOT_A_PDO_MODULE:dbname=pdo;host=localhost",
"postgres8",
"postgres8"
);
}
catch( PDOException $e )
{
die( $e->getMessage() );
}
echo "Successfully created a PDO object";
?>

我们会得到

could not find driver

SQLSTATE[HY000] [7] FATAL: database "pdo2" does not exist

如果数据库不存在(不同的错误会返回不同的提示信息)。

2. 设置属性

1) PDO有三种错误处理方式:

• PDO::ERRMODE_SILENT不显示错误信息,只设置错误码
• PDO::ERRMODE_WARNING显示警告错
• PDO::ERRMODE_EXCEPTION抛出异常

可通过以下语句来设置错误处理方式为抛出异常

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

当设置为PDO::ERRMODE_SILENT时可以通过调用errorCode() 或errorInfo()来获得错误信息,当然其他情况下也可以。

2) 因为不同数据库对返回的字段名称大小写处理不同,所以PDO提供了PDO::ATTR_CASE设置项(包括PDO::CASE_LOWER,PDO::CASE_NATURAL,PDO::CASE_UPPER),来确定返回的字段名称的大小写。

3) 通过设置PDO::ATTR_ORACLE_NULLS类型(包括PDO::NULL_NATURAL,PDO::NULL_EMPTY_STRING,PDO::NULL_TO_STRING)来指定数据库返回的NULL值在php中对应的数值。

3. 查询

为了说明清楚,我们这里定义了一个RSS feeds表

id integer
name character varying(100)
url varharacter varying(255)
feed character varying(255)

不使用预处理语句的方式:

foreach( $db->query( "SELECT * FROM feeds" ) as $row )
{
print_r( $row );
}
?>

得到以下结果:

Array
(
[id] => 1
[0] => 1
[name] => Planet-PHP
[1] => Planet-PHP
[url] => http://www.planet-php.net
[2] => http://www.planet-php.net
[feed] => http://www.planet-php.net/rdf/
[3] => http://www.planet-php.net/rdf/
)
(只显示已行为了节省空间)

使用预处理语句的方式:

$stmt = $db->prepare( "SELECT * FROM feeds" );
$stmt->execute();
print_r( $stmt->fetch() );
?>

这里,$stmt是一个PDOStatement对象,预处理之后会得到这样一个对象,必须execute后才起作用。fetch函数只提取了一行数据,如果需要读取全部数据,可换成fetchAll函数。

绑定数据

$stmt = $db->prepare( "SELECT * FROM feeds WHERE url = :url" );
$url = "http://www.planet-php.net";
$stmt->bindParam( ":url", $url );
$stmt->execute();
while( $row = $stmt->fetch() )
{
print_r( $row );
}
?>

这里,bindParam将$url变量绑定到了:url域,执行时会自动将改变量载入。

插入数据

$stmt = $db->prepare(
"INSERT INTO feeds
( name, url, feed )
VALUES
( :name, :url, :feed )"
);

$stmt->execute(
array(
":name" => "Planeti Apache",
":url" => "http://www.planetapache.org",
":feed" => "http://www.planetapache.org/rss10.xml"
)
);
?>

实现插入数据也可以像绑定数据一样来quote数据,这里给出通过在execute中给定输入参数来自动quote的方法。

事务处理

$dbh->beginTransaction();
try {
$dbh->query("UPDATE ...");
$dbh->query("UPDATE ...");
$dbh->commit();
} catch (Exception $e) {
$dbh->rollBack();
}

如果数据库支持事务处理,调用beginTransaction的同时将数据库设置为非自动提交,commit或rollBack返回自动提交状态。

4. 存储过程

$stmt = $dbh->prepare("CALL sp_set_string(?)");
$stmt->bindParam(1, $str);
$str = ‘foo’;
$stmt->execute();

于先前的例子差不多,只是这里使用了“?”数据绑定方法,sp_set_string是存储过程名称。

带有输出参数的存储过程

$stmt = $dbh->prepare("CALL sp_get_string(?)");
$stmt->bindParam(1, $ret,PDO:ARAM_STR, 4000);
if ($stmt->execute()) {
echo "Got $ret\n";
}

绑定列输出

$stmt = $dbh->prepare("SELECT extension, name from CREDITS");
if ($stmt->execute()) {
$stmt->bindColumn('extension', $extension);
$stmt->bindColumn('name', $name);
while ($stmt->fetch(PDO::FETCH_BOUND)) {
echo "Extension: $extension\n";
echo "Author: $name\n";
}
}
grant all privileges on *.* to 'a'@'localhost' identified by 'a' with grant option;flush privileges;
快速回复
限100 字节
 
上一个 下一个