PHP之PDO扩展技术总结

182次阅读
没有评论

执行 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

正文完
有偿技术支持加微信
post-qrcode
 
评论(没有评论)
验证码