Oraclephp的mysql\mysqli\PDO(三)PDO

初稿链接:http://www.orlion.ga/1153/

PDO是如出一辙栽数据库抽象层,不止可以看mysql还好看其他数据库。

 

一、__construct()

PDO::__construct ( string $dsn [, string $username [, string $password [, array$driver_options ]]] )

    $dsn:通常,一个
DSN 由 PDO
驱动名、紧随其后的冒号、以及可选的驱动程序的数据库连接变量信息,如主机名、端口与数据库名。例:oci:dbname=//localhost:1521/my_db(这种是连接Oracle数据库的数目源名)mysql:host=localhost;dbname=testdb(这种是连接mysql服务器的数码源名)。php.ini中可装DSN信息:pdo.dsn.oraclepdo=”OCI:dbname=//localhost:1521/my_db;charset=UTF-8″;在开创PDO对象时虽得:new
PDO(“oraclepdo”, …);

    $driver_options数组用来指定具体驱动的连续选项,形式是“键=>值”对,一些常用之抉择项:

    Oracle 1

    例:

try{
    $db = newpdo('mysql:host=127.0.0.1;port=3306;dbname=mysql;charset=utf8','user','password',array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ));
}catch(PDOException $pe){
    echo $pe->getMessage();
}

 

若果无法加载驱动或连续失败会抛来一个PDOException。

二、setAttribute()、getAttribute()方法

    可以调用setAttribute()方法呢PDO对象设置属性,可以调动PDO的表现及脚驱动状态,而getAttribute()可以博属性,例:

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

    Oracle数据库在用空字符串返回给PDO时会将空字符串转为PHP的NULL,但是其他的数据库不这样做,这便带了可移植性问题,不过PDO提供了一个驱动程序级属性PDO::ATTR_ORACLE_NULLS,该属性可以啊外数驱动套此行为,此属性设置也TRUE,在取得时可拿空字符串转为NULL。

 

三、exec()、query()

    当尽长删改操作时不曾返回值可以调用PDO对象的exec方法执行SQL,该方法返回给影响的实践,所以发生或会见回去回0,但是实施是马到成功的,所以判断返回值时行使$affected
=== TRUE。例:

$affected = $db->exec("insert into or_users(user_login, user_pass)values('u1', 'p1')");
if (FALSE === $affected) {
    echo 'Error';
}

   
当尽select操作时采取query(),该措施返回PDOStatement对象,可以调用PDOStatement对象的rowCount()方法查看返回的行数,例:

$pdostatement = $db->query("select user_login, user_pass from or_users");
foreach ($pdostatement as $row) {
    print_r($row);
}

    函数原型:

public PDOStatement PDO::query ( string $statement )
public PDOStatement PDO::query ( string $statement , int $PDO::FETCH_COLUMN , int $colno )
public PDOStatement PDO::query ( string $statement , int $PDO::FETCH_CLASS , string$classname , array $ctorargs )
public PDOStatement PDO::query ( string $statement , int $PDO::FETCH_INTO , object $object)

四、预处理

    PDO支持以占位符(?)语法将变量绑定到SQL中之预处理语句,预处理语句的用意是编译一坏,多次运行,会于服务器上缓存查询的语法和行进程,而以服务器和客户端里传递出生成的列值。可以防范SQL注入,而且执行进度比较query()、exec()快。

    1、PDOStatement对象

    query()方法返回的PDOStatement对象是结果集对象,而prepare()方法返回的PDOStatement对象是询问对象,PDOStatement中之普成员方法如下:

    Oracle 2

    2、准备语句

    重复执行一个sql语句只不过每次执行的参数有或不同,这时用预处理语句效率最高。PDO有些许栽占位符语法”命名参数”:

$db->prepare("insert into or_users(user_login, user_pass)values(:user_login, :user_pass)");

    “问号参数”:

$db->prepare("insert into or_users(user_login, user_pass)values(?, ?)");

    prepare()方法返回PDOStatement类对象,原型:

public PDOStatement PDO::prepare ( string $statement [, array $driver_options = array() ] )

    3、绑定参数和实施

    当SQL准备好之后下同样步就是是吃SQL绑定参数了,可以由此PDOStatement对象的bindParam()方法将参数绑定到占位符上:

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )

    $parameter:参数标识符。对于以命名占位符的优先处理语句,应是看似 :name 形式之参数称为。对于利用问号占位符的预处理语句,应是以1上马索引的参数位置。

    &$variable:该参数提供被第一单参数所指定占位符的价。可以见到一个”&”符,它用依照引用传递,在成准备下存储过程用这方式时方可因存储过程的某个动作修改者价。因为拖欠参数是依引用传递,所以不得不提供变量作为参数,不能够一直提供价值。

    $data_type:为当下绑定的参数设置数据类型。可选值:

PDO::PARAM_BOOL: 代表boolean数据类型
PDO::PARAM_NULL: 代表SQL中NULL类型
PDO::PARAM_INT: 代表SQL中INTEGER数据类型
PDO::PARAM_STR: 代表SQL中CHAR、VARCHAR和其他字符串数据类型
PDO::PARAM_LOB: 代表SQL中大对象数据类型。
PDO::PARAM_STMT: 代表PDOStatement对象类型
PDO::PARAM_INPUT_OUTPUT: 专为存储过程使用的数据类型,可以在过程执行后修改

    $length: 可挑选,数据类型的长。为标志参数是一个囤过程的
OUT 参数,必须明白地安装这个尺寸。

    $driver_options: 可选。

    例:

$sql = 'insert into or_users(user_login, user_pass)values(:user_login, :user_pass)';
$stmt = $this->conn->prepare($sql);
$user_login = 'u2';
$user_pass = 'p2';
// $stmt->bindParam(':user_login', 'u2');这种方式是错的,参数不能是具体的值只能是变量
$stmt->bindParam(':user_pass', $user_login);// 这种是正确的
$stmt->bindParam(':user_pass', $user_pass);
$stmt->execute();

// 下面可以改变变量的值继续插入
$user_login = 'u3';
$user_pass = 'p3';
$stmt->execute();

    另外还有雷同栽更速的方法:

$sql = 'insert into or_users(user_login, user_pass)values(:user_login, :user_pass)';
$stmt = $this->conn->prepare($sql);
$stmt->execute(array(':user_login' => 'u3', ':user_pass' => 'p3'));   

    execute()方法回布尔值

    4、获取结果

    query()与prepare()+execute()返回的结果是平等的,都待经PDOStatement对象的章程以结果遍历出来。

    (1)fetch()方法

    原型:

mixed PDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )

    该措施返回结果集的目前行记录并以结果集指针指向下一行,当到达结果集末尾的时节回来FALSE.

    $fetch_style:控制下一行如何回到给调用者,此值必须是 PDO::FETCH_** 系列常量中之一个,缺省为PDO::ATTR_DEFAULT_FETCH_MODE 的值
(默认为 
PDO::FETCH_BOTH* )

    

  • PDO::FETCH_ASSOC:返回一个目为结果集列名的数组

  • PDO::FETCH_BOTH(默认):返回一个目录为结果集列名和以0开始之列号的数组

  • PDO::FETCH_BOUND:返回 TRUE ,并分配结果集中之列值给PDOStatement::bindColumn() 方法绑定的
    PHP 变量。

  • PDO::FETCH_CLASS:返回一个告求类的新实例,映射结果集中之列名到接近吃对应的属于性名。如果 fetch_style 包含
    PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS |
    PDO::FETCH_CLASSTYPE
    ),则类名由第一排的价决定

  • PDO::FETCH_INTO:更新一个为呼吁求类已存在的实例,映射结果集中之列到类吃命名的特性

  • PDO::FETCH_LAZY:结合使用 PDO::FETCH_BOTH 和 PDO::FETCH_OBJ,创建供用来做客的目标变量名

  • PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组

  • PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象

    $cursor_orientation:可选,用来规定目标是一个但滚动的游标时应有获得哪一行。

    $cursor_offset:可选,整数值,表示如博的行相对于即游标位置的撼动。

    

    (2)fetchAll()方法

    该办法同样潮获得结果集中具有数据赋给返回的数组:

array PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array$ctor_args = array() ]]] )

    $fetch_style:控制返回数组的始末似 PDOStatement::fetch() 文档中记载的如出一辙。默认为PDO::ATTR_DEFAULT_FETCH_MODE 的价值(
其欠省值为 PDO::FETCH_BOTH )

相思只要回到一个蕴含结果集中单独一排列所有值的再三组,需要指定 PDO::FETCH_COLUMN 。通过点名 column-index 参数获取想只要之排。

顾念如果落结果集中单独一列的唯一值,需要拿 PDO::FETCH_COLUMN 和 PDO::FETCH_UNIQUE 按位或。

思只要回来一个根据指定列管价值分组后底涉数组,需要用 PDO::FETCH_COLUMN 和PDO::FETCH_GROUP 按位或。

    $fetch_argument:可选,是一个平头索引,当在fetchAll()方法的首先单参数中指定PDO::FETCH_COLUMN值时,从结果集中返回经过该参数提供的目录所指定列的享有值。

    

    (3)setFetchMode()

    为语句设置默认的获模式。

    (4)bindColumn()

    该办法好拿一个排和一个指定的变量名绑定,这样每次用fetch方法取得各行记录时,会活动将相应的列值付给该变量,但得是以fetch()方法的首先单参数设置为PDO::FETCH_BOTH值时,原型:

bool PDOStatement::bindColumn ( mixed $column , mixed &$param [, int $type [, int $maxlen [,mixed $driverdata ]]] )

    $column:可以行使整数的列偏移位置索引(索引值于1起),或是列的称呼字符串

    $param:需要传递一个援,所以要提供一个变量叫

    $type:可选,通过安装变量的类来限制变量值,该参数支持之价和bindParam()方法同样。

    例:

$sql = 'select user_login, user_pass from or_users';
$stmt = $db->prepare($sql);
$stmt->execute();
$stmt->bindColumn(1, $user_login);
$stmt->bindColumn('user_pass', $user_pass);

while($row = $stmt->fetch()) {
    echo $user_login . $user_pass . '<br/>';
}

    5、大数据对象的存取
    有时候会当数据库被存储一个交由比较坏之数据(图片、音乐、电影)(当然这种设计无绝合理)。PDO运行于bindParam()和bindColumn()调用中经过采用PDO::PARAM_LOB类型代码来用大型数据类型。PDO::PARAM_LOB告诉PDO将数据映射为流动,所以可以采用PHP中文件处理函数来操作这种多少。例:

    Oracle 3

五、事务

 非每种数据库都支持工作,因此当第一涂鸦打开连接时,PDO
需要以所谓的“自动提交”模式下运行。自动提交模式代表,如果数据库支持,运行的每个查询都来它好之隐式事务,如果数据库不支持工作,则无。如果要一个事务,则必须用 PDO::beginTransaction() 方法来启动。如果底层驱动不支持工作,则弃来一个
PDOException
异常(不管错误处理设置是哪的,这还是一个重的失实状态)。一旦开始了政工,可用PDO::commit() 或 PDO::rollBack()来完成,这取决事务中的代码是否运行成功。

    PDO
仅以叫层检查是不是享有事务处理能力
。如果某些运行时规格意味着工作不可用,且数据库服务接受请求去启动一个作业,PDO::beginTransaction() 将依旧返回 TRUE 而且没有错误。试着在
MySQL 数据库的 MyISAM
数据表中使用工作就是一个不行好之例证。

    当脚论了或连续即将于关时,如果还有一个未就的政工,那么
PDO 将机关回滚该业务。

    只有经 PDO::beginTransaction() 启动一个业务后,才可能有自动回滚。如果手动发出同样修查询启动工作,
则 PDO 无法掌握,从而在必要时莫可知拓展回滚。

    贴单PHP手册中举的例子:

<?php
try {
  $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', 
      array(PDO::ATTR_PERSISTENT => true));
  echo "Connected\n";
} catch (Exception $e) {
  die("Unable to connect: " . $e->getMessage());
}

try {  
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $dbh->beginTransaction();
  $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
  $dbh->exec("insert into salarychange (id, amount, changedate) 
      values (23, 50000, NOW())");
  $dbh->commit();
  
} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}
?>

 

六、贴一个单例类

<?php
namespace DB;

use PDO;
use PDOException;
use Exception;

class DBPDO
{
    const DB_USER = 'root';

    const DB_PWD  = '';

    const DB_DSN = 'mysql:host=127.0.0.1:3306;dbname=orlion';

    private static $DB_OPT = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ORACLE_NULLS => TRUE);

    private $conn;

    private static $_instance = null;

    private function __construct()
    {
        $this->conn = new PDO(self::DB_DSN, self::DB_USER, self::DB_PWD, self::$DB_OPT);
    }

    private function __clone()
    {

    }

    public static function getInstance()
    {
        if (is_null(self::$_instance) || !self::$_instance instanceof self) {
                try {
                self::$_instance = new self();
            } catch (PDOException $pe) {
                // 这里应该抛一个自定义异常以便上层处理
                throw new Exception('Could not connect to database:' . self::DB_DSN);
            }
        }

        return self::$_instance;
    }

    public function query($sql)
    {
        return $this->conn->query($sql);
    }

    public function update($sql)
    {
        return $this->conn->exec($sql);
    }

    public function __destruct()
    {
        unset($this->conn);
    }
}
?>

相关文章