PDO使用简介

来源:互联网 发布:mmd双人姿势数据 编辑:程序博客网 时间:2024/06/07 20:12

出处:http://www.phpchina.cn/bbs/viewthread.php?tid=1574&fpage=1&highlight=%2Bmzt

 

 

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对象。

<?php
$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模块。如果我们试图处理一个无效的连接字符串:

<?php
$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异常来处理错误(但并不是所有情况都是)。

<?php
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)        

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

<?php
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/
)
(只显示已行为了节省空间)

使用预处理语句的方式:

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

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

绑定数据

<?php
$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域,执行时会自动将改变量载入。

插入数据

<?php
$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::PARAM_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";
}
}