PHP 数据对象

简介

PHP 数据对象PDO)扩展为 PHP 访问数据库定义了一个轻量级的一致接口。实现 PDO 接口的每个数据库驱动可以将特定具体数据库的特性公开作为标准扩展函数。注意不能单独使用 PDO 扩展执行任何数据库功能;必须使用具体数据库的 PDO 驱动程序来访问数据库服务器。

PDO 提供了数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数来查询和获取数据。PDO 提供数据库抽象;不会重写 SQL 或模拟缺失的特性。如果需要,应该使用成熟的抽象层。

PDO 随 PHP 一起提供。

添加备注

用户贡献的备注 5 notes

up
123
djlopez at gmx dot de
19 years ago
Please note this:

Won't work:
$sth = $dbh->prepare('SELECT name, colour, calories FROM ?  WHERE calories < ?');

THIS WORKS!
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ?');

The parameter cannot be applied on table names!!
up
5
wiserufferto at gmail dot com
5 years ago
This is a little late... but I'm old and slow.......
Regarding Extending PDOStatement and PDO I found that sending the PDOExtended class by reference helps:
    In the constructor after parent::__construct() :
$this->setAttribute(\PDO::ATTR_STATEMENT_CLASS,array('PDOStatementExtended', [&$this]));}

And in 
class PDOStatementExtended extends \PDOStatement
{
  
  protected function __construct
  (
    \PDO &$PDO,
   )
up
11
pokojny at radlight dot com
19 years ago
I wanted to extend PDO class to store statistics of DB usage, and I faced some problems. I wanted to count number of created statements and number of their executings. So PDOStatement should have link to PDO that created it and stores the statistical info. The problem was that I didn't knew how PDO creates PDOStatement (constructor parameters and so on), so I have created these two classes:

<?php
/**
 * PHP Document Object plus
 * 
 * PHP Document Object plus is library with functionality of PDO, entirely written
 * in PHP, so that developer can easily extend it's classes with specific functionality,
 * such as providing database usage statistics implemented in v1.0b
 * 
 * @author Peter Pokojny
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */
    class PDOp {
        protected $PDO;
        public $numExecutes;
        public $numStatements;
        public function __construct($dsn, $user=NULL, $pass=NULL, $driver_options=NULL) {
            $this->PDO = new PDO($dsn, $user, $pass, $driver_options);
            $this->numExecutes = 0;
            $this->numStatements = 0;
        }
        public function __call($func, $args) {
            return call_user_func_array(array(&$this->PDO, $func), $args);
        }
        public function prepare() {
            $this->numStatements++;
            
            $args = func_get_args();
            $PDOS = call_user_func_array(array(&$this->PDO, 'prepare'), $args);
            
            return new PDOpStatement($this, $PDOS);
        }
        public function query() {
            $this->numExecutes++;
            $this->numStatements++;
            
            $args = func_get_args();
            $PDOS = call_user_func_array(array(&$this->PDO, 'query'), $args);
            
            return new PDOpStatement($this, $PDOS);
        }
        public function exec() {
            $this->numExecutes++;
            
            $args = func_get_args();
            return call_user_func_array(array(&$this->PDO, 'exec'), $args);
        }
    }
    class PDOpStatement implements IteratorAggregate {
        protected $PDOS;
        protected $PDOp;
        public function __construct($PDOp, $PDOS) {
            $this->PDOp = $PDOp;
            $this->PDOS = $PDOS;
        }
        public function __call($func, $args) {
            return call_user_func_array(array(&$this->PDOS, $func), $args);
        }
        public function bindColumn($column, &$param, $type=NULL) {
            if ($type === NULL)
                $this->PDOS->bindColumn($column, $param);
            else
                $this->PDOS->bindColumn($column, $param, $type);
        }
        public function bindParam($column, &$param, $type=NULL) {
            if ($type === NULL)
                $this->PDOS->bindParam($column, $param);
            else
                $this->PDOS->bindParam($column, $param, $type);
        }
        public function execute() {
            $this->PDOp->numExecutes++;
            $args = func_get_args();
            return call_user_func_array(array(&$this->PDOS, 'execute'), $args);
        }
        public function __get($property) {
            return $this->PDOS->$property;
        }
        public function getIterator() {
            return $this->PDOS;
        }
   }
?>

Classes have properties with original PDO and PDOStatement objects, which are providing the functionality to PDOp and PDOpStatement.
From outside, PDOp and PDOpStatement look like PDO and PDOStatement, but also are providing wanted info.
up
0
dougwilbourne at gmail dot com
1 year ago
Now that current versions of MySQL are forcing users to authenticate with caching_sha2_password instead of mysql_native_driver, I wanted to get PDO to send passwords that way.  I think the only way to do it is to make the connection over SSL. Setting up your web server and database server for SSL is way beyond the scope of this note, but after you do, remember that you will need to add an options array as the last argument in your PDO connection arguments.  At a minimum, you will need to supply the server certificate.  In a development environment with a self-signed server certificate, you will also want to bypass verification that your server certificate is 'real'.  So your options array would look like this

$opts = [ PDO::MYSQL_ATTR_SSL_CA => $server_cert_file_path, PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false];

Hope it helps!
up
-2
www.navin.biz
20 years ago
Below is an example of extending PDO & PDOStatement classes:

<?php

class Database extends PDO
{
    function __construct()
    {
        parent::__construct('mysql:dbname=test;host=localhost', 'root', '');
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this)));
    }
}

class DBStatement extends PDOStatement
{
    public $dbh;

    protected function __construct($dbh)
    {
        $this->dbh = $dbh;
        $this->setFetchMode(PDO::FETCH_OBJ);
    }
    
    public function foundRows()
    {
        $rows = $this->dbh->prepare('SELECT found_rows() AS rows', array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE));
        $rows->execute();
        $rowsCount = $rows->fetch(PDO::FETCH_OBJ)->rows;
        $rows->closeCursor();
        return $rowsCount;
    }
}

?>
To Top