PHP之PDO扩展技术总结

作者: JONE 分类: 编程 发布时间: 2017-08-18 13:32

执行sql语句: exec() 、query()、 perpare();

1、query用来处理有结果集的,如select, 返回 PDOStatement 对象,失败返回false(当为 PDO::ERRMODE_SILENT,这也是默认的值)
2、exec用来处理有返回影响行数的(int),如  insert(插入的行数)、 delete(删除的行数) 、update(和原数值不等才算), 失败返回false (当为 PDO::ERRMODE_SILENT,这也是默认的值)

3、prepare 执行所有sql,可以完全替代 query,exec的功能

错误报告是针对执行的sql出错时

PDO::ERRMODE_SILENT(0) :默认 不提示任何错误 ,连接时无论如何都会提示,只有在执行后面的方法时才会起作用
PDO::ERRMODE_WARNING(1) : 警告
PDO::ERRMODE_EXCEPTION(2):异常(推荐使用) 用try catch捕获,也可以手动抛出异常 new PDOException($message, $code, $previous)

一 PDO基本认识

什么事PDO

POD(PHP Data Object)扩展在PHP5中加入,PHP6中将默认识用PDO连接数据库,所有非PDO扩展将会在PHP6被从扩展中移除。该扩展提供PHP内置类 PDO来对数据库进行访问,不同数据库使用相同的方法名,解决数据库连接不统一的问题。

如何开启PDO扩展

① 找到php目录下的php.ini配置文件

② 开启pdo_mysql.dll扩展(按需加载)

;开启php_pdo_mysql数据对象扩展
 extension=php_pdo_mysql.dll

③ 重启Apache软件

④使用phpinfo函数判断pdo_mysql是否开启成功

二 、 PDO::__construct    创建一个表示数据库连接的 PDO (实例的对象)

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

$dsn :数据源 ,字符串类型 ,格式:mysql:host=localhost;dbname=project

$username :用户名,连接数据库的用户名

$password :密码,连接数据库的密码

<?php
/*如果试图连接到请求的数据库失败,则PDO::__construct() 抛出一个 PDO异常(PDOException)*/
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';   //数据库用户名
$password = 'dbpass';  //数据库密码

try {
 $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
 echo 'Connection failed: ' . $e->getMessage();
}

?>

三、PDO::exec     执行一条 SQL 语句,并返回受影响的行数(数据的增删改)

int PDO::exec ( string $statement )

PDO::exec() 在一个单独的函数调用中执行一条 SQL 语句,返回受此语句影响的行数。

PDO::exec() 不会从一条 SELECT 语句中返回结果。对于在程序中只需要发出一次的 SELECT 语句,可以考虑使用 PDO::query()。对于需要发出多次的语句,可用 PDO::prepare() 来准备一个 PDOStatement 对象并用 PDOStatement::execute() 发出语句。

此函数可能返回布尔值 FALSE,但也可能返回等同于 FALSE 的非布尔值(没有受影响的行,则 PDO::exec() 返回 0,判断是布尔值false还是0时可以用 !== 或者 === 进行全比较)。

<?php
$dbh = new PDO('odbc:sample', 'db2inst1', 'ibmdb2');

/* 删除 FRUIT 数据表中满足条件的所有行 */
$count = $dbh->exec("DELETE FROM fruit WHERE colour = 'red'");

/* 返回被删除的行数 */
print("Deleted $count rows.\n");
?> 
以上例程会输出:

Deleted 1 rows.

四、PDO::query  执行一条SQL语句,返回一个结果集作为PDOStatement对象

<?php
header("content-type:text/html;charset=utf-8");

$params = array (
 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' ,
 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
 );
$pdo = new PDO('mysql:host=127.0.0.1;dbname=bbs;port=3306', 'root', 'root',$params);

$statement = "select * from user";

$stmt = $pdo->query($statement);

echo "<pre>";
var_dump($stmt);


/*
以下是输出的结果,可以看出返回一个结果集作为PDOStatement对象
object(PDOStatement)#2 (1) {
 ["queryString"]=>
 string(18) "select * from user"
}
*/
?>

注意:
1、query和exec都可以执行所有的sql语句,只是返回值不同而已。
2、query可以实现所有exec的功能。
3、当把select语句应用到 exec 时,总是返回 0

五、PDO中的遍历操作

要使用到的知识点:

  • mixed PDOStatement::fetch (int $fetch_style) :实现对数据的遍历输出,每次只能遍历一条记录,然后指针向下移动一位!

参数说明:

PDO::FETCH_ASSOC :把一条记录遍历到关联数组中

PDO::FETCH_NUM :把一条记录遍历到索引型数组中

PDO::FETCH_BOTH :把一条记录遍历到混合型数组中

PDO::FETCH_OBJ :把一条记录遍历到对象中

PDO::FETCH_BOUND (bindColumn) :把某个变量绑定到结果集中的某个列

示例代码:PDO::FETCH_ASSOC

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "select * from tb_admin";
 //4、执行SQL语句
 $stmt = $pdo->query($sql);
 //5、获取总记录数
 $count = $stmt->rowCount();
 //6、遍历数据到关联数组中
 for($i=0;$i<$count;$i++) {
 //把一条记录遍历到关联型数组中
 $row = $stmt->fetch(PDO::FETCH_ASSOC);
 var_dump($row);
 }
?>

示例代码:PDO::FETCH_BOUND(bindColumn)

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "select * from tb_admin";
 //4、执行SQL语句
 $stmt = $pdo->query($sql);
 $count = $stmt->rowCount();
 //5、使用bindColumn实现列绑定
 $stmt->bindColumn(1,$id); //把变量$id绑定到结果集中的第1列
 $stmt->bindColumn(2,$username); //把变量$username绑定到结果集中的第2列
 $stmt->bindColumn(3,$password); //把变量$password绑定到结果集中的第3列
 //6、使用for循环实现对结果集的遍历
 for($i=0;$i<$count;$i++) {
 //指定fetch的绑定方式为PDO::FETCH_BOUND,否则bindColumn不会生效
 $stmt->fetch(PDO::FETCH_BOUND);
 //输出$id/$username以及$password的基本信息
 echo $id;
 echo '-';
 echo $username;
 echo '-';
 echo $password;
 echo '<hr />';
 }
?>

要用到的知识点:

  • array PDOStatement::fetchAll()

主要功能:把数据表中的记录返回到一个二维数组中

示例代码:

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "select * from tb_admin";
 //4、执行SQL语句
 $stmt = $pdo->query($sql);
 //5、把数据表中的所有记录返回到一个二维数组中
 $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
 //6、遍历结果集
 foreach($data as $row) {
 echo $row['id'];
 echo '-';
 echo $row['username'];
 echo '-';
 echo $row['password'];
 echo '<hr />';
 }
?>

要用到的知识点:

  • string PDOStatement::fetchColumn ([ int $column_number = 0 ] )

主要功能:遍历结果集当前行的某一列信息

参数说明:

$column_number :第几列,从0开始

示例代码:

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "select * from tb_admin";
 //4、执行SQL语句
 $stmt = $pdo->query($sql);
 //5、获取总记录数
 $count = $stmt->rowCount();
 //6、使用for循环遍历结果集
 for($i=0;$i<$count;$i++) {
 $id = $stmt->fetchColumn(0);
 echo $id.'<hr />';
 }
?>

六、PDO扩展中的预处理功能

  • PDO::prepare ( string $statement) :定义预处理语句 返回值为PDOStatement对象或者为false
  • PDOStatement::execute ([ array $input_parameters ] ) :执行预处理语句 返回值为布尔值
  • PDOStatement::bindParam ( mixed $parameter , mixed &$variable) 实现参数绑定
    返回值为布尔值
    $parameter :要绑定的参数    $variable :要设置的参数值,按引用传递
    特别注意:如果以上参数,使用的是?问号标识,其绑定时索引是从1开始的

预处理功能就是在SQL语句结构与形式相同的情况下,只有参数不同所采用的一种数据处理机制,其极大的减少了带宽的浪费。

示例①使用文本标识

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "insert into tb_admin values (null,:username,:password,:time)";
 //4、定义预处理语句
 $stmt = $pdo->prepare($sql);
 //5、使用execute实现参数的传递
 $password = md5('123456');
 $time = time();
 $data = array(
 ':username'=>'zhangsan',
 ':password'=>$password,
 ':time'=>$time
 );
 $stmt->execute($data);
?>

示例②使用问号标识

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "insert into tb_admin values (null,?,?,?)";
 //4、定义预处理语句
 $stmt = $pdo->prepare($sql);
 //5、使用execute传递参数
 $password = md5('123456');
 $time = time();
 $data = array(
 0=>'lisi',
 1=>$password,
 2=>$time
 );
 $stmt->execute($data);
?>

示例③使用文本标识时参数绑定

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "insert into tb_admin values (null,:username,:password,:time)";
 //4、定义预处理语句
 $stmt = $pdo->prepare($sql);
 //5、绑定参数
 $stmt->bindParam(':username',$username);
 $stmt->bindParam(':password',$password);
 $stmt->bindParam(':time',$time);
 //6、设置参数
 $username = 'wangwu';
 $password = md5('123456');
 $time = time();
 //7、执行预处理语句
 $stmt->execute();
?>

示例④使用?标识参数绑定时

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、组装SQL语句
 $sql = "insert into tb_admin values (null,?,?,?)";
 //4、定义预处理语句
 $stmt = $pdo->prepare($sql);
 //5、使用bindParam实现参数绑定
 $stmt->bindParam(1,$username);
 $stmt->bindParam(2,$password);
 $stmt->bindParam(3,$time);

//6、设置参数
 $username = 'zhaoliu';
 $password = md5('123456');
 $time = time();
 //7、执行预处理语句
 $stmt->execute();

$username = 'tianqi';
 $password = md5('123456');
 $time = time();
 $stmt->execute();
 ?>

七、PDO中事务处理

事务处理主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

在事务处理中,所有步骤(操作)要么都成功,要么都失败。如果所有步骤都成功,则认为事务处理成功。如果有一个步骤出现了问题,则认为事务处理失败。

① 开启事务 bool PDO::beginTransaction ( void )

② 提交事务 bool PDO::commit ( void )

③ 回滚事务 bool PDO::rollBack ( void )

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";
 $pdo = new PDO($dsn, $user, $pass);
 //3、开启事务处理
 $pdo->beginTransaction();
 //4、定义交易流程(两个步骤:扣钱与加钱)
 $flag = true;
 $sql = "update tb_bank set money = 2000 where id = 1";
 $affected_rows = $pdo->exec($sql);
 if(!$affected_rows) {
 $flag = false;
 }
 $sql = "update tb_bank set money = 0.1 where id = 3";
 $affected_rows = $pdo->exec($sql);
 if(!$affected_rows) {
 $flag = false;
 }
 //5、判断交易是否成功
 if($flag) {
 //交易成功,提交事务
 $pdo->commit();
 } else {
 //交易失败,回滚事务
 $pdo->rollback();
 }
?>

八、PDO中的异常类

PHP 5 提供了一种新的面向对象的错误处理方法。

异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。

PDO中的异常捕获基本语法:

try {

存在潜在错误的代码;

if(逻辑错误) {

//手工输出异常

throw  new  PDOException(‘错误的文本信息’,’错误号’);

}

} catch(PDOException $e) {

echo ‘错误号:’.$e->getCode();

echo ‘错误行号:’.$e->getLine();

echo ‘错误的文本信息:’.$e->getMessage();

}

示例代码

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、定义相关参数
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dsn = "$dbms:host=localhost;dbname=project";
 //3、实例化pdo类
 try {
 $pdo = new PDO($dsn,$user,$pass);
 //4、定义SQL语句
 $time = time();
 $sql = "insert into tb_admin values (null,abcd,'123456',$time)";
 $flag = $pdo->exec($sql);
 //5、手工抛出异常
 if($flag === false) {
 throw new PDOException('SQL语句错误',1000);
 }
 } catch(PDOException $e) {
 echo '错误号:'.$e->getCode().'<hr />';
 echo '错误行:'.$e->getLine().'<hr />';
 echo '错误信息:'.$e->getMessage();
 }
?>

九、PDO中属性的获取与设置

1、属性的获取与设置

要用到的知识点:

设置 :set  获取 :get  属性 :attribute

bool PDO::setAttribute ( int $attribute , mixed $value ) :设置属性

mixed PDO::getAttribute ( int $attribute ) :获取属性

参数说明:

$attribute :要设置或获取的属性

$value :要设置的属性值

2、PDO中常用的属性

① PDO::ATTR_AUTOCOMMIT :自动提交,常用于事务处理(语句事务)

参数值:

1 :自动提交

0 :关闭自动提交

 

② PDO::ATTR_CASE :结果集大小写

参数值:

PDO::CASE_LOWER(2) :把结果集(字段名称)全部转化为小写

PDO::CASE_UPPER(1) :把结果集(字段名称)全部转化为大写

PDO::CASE_NATURAL(0) :正常返回

 

③ PDO::ATTR_PERSISTENT :长连接

名词解析:

短连接 :连接 à 发送SQL语句 à 执行SQL语句  à  关闭

长连接 :连接 à a发送SQL语句 à 执行SQL语句  à  a发送SQL语句 à 执行SQL语句 …

 

示例代码

<?php
 //1、设置响应头信息
 header('Content-type:text/html; charset=utf-8');
 //2、实例化pdo类
 $dbms = 'mysql';
 $user = 'root';
 $pass = 'mysql';
 $dbname = 'project';
 $dsn = "$dbms:host=localhost; dbname=$dbname";

//设置长连接
 $data = array(PDO::ATTR_PERSISTENT=>true);
 $pdo = new PDO($dsn, $user, $pass, $data);
 //3、设置常用属性
 $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0); //关闭自动提交
 $pdo->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER); //结果集字段全部转化为小写

//4、获取常用属性值
 echo '自动提交:';
 var_dump($pdo->getAttribute(PDO::ATTR_AUTOCOMMIT));
 echo '<hr />';

echo '结果集大小写:';
 var_dump($pdo->getAttribute(PDO::ATTR_CASE));
 echo '<hr />';

echo '长连接:';
 var_dump($pdo->getAttribute(PDO::ATTR_PERSISTENT));
 echo '<hr />';
?>

十、总结

① PDO扩展技术

PDO的基本概念以及为什么需要PDO

② PDO类(增删改查)

增删改:$pdo->exec($sql) 返回受影响的行数

查询:$pdo->query($sql) 返回PDOStatement类,fetch方法、fetchAll方法、fetchColumn方法

③ PDO中的预处理

减少SQL语句的传递,只传递相关的参数,这样可以减少带宽的浪费

prepare  stmt1  from  ‘insert into tb_admin values (null,?,?,?)’;

设置参数

set @参数 = 参数的值;

执行预处理

execute  stmt1  using  @参数;

④ PDO中的事务处理

开启事务beginTransaction()

提交事务commit()

回滚事务rollback()

⑤ 异常类PDOException

try {

//存在潜在错误的语句

if(逻辑错误) {

//手工抛出异常

throw  new  PDOException(‘错误信息’,’错误号’);

}

} catch(PDOException $e) {

echo $e->getCode();

echo $e->getLine();

echo $e->getMessage();

}

⑥ 属性的设置与获取

setAttribute

getAttribute