PHP下PDO操作流程
来自MordenPHP的PDO篇
说明: 什么是PDO?
pdo是Php Data Object的缩写,php数据对象。
怎么开启PDO:
php版本低于5.3
1.打开php.ini配置文件,找到extension=php_pdo.dll选项,去掉注释;
2.找到需要开启的pdo数据库支持选项,例如开启MYSQL支持,去掉extension=php_pdo_mysql.dll前面的注释
3.重启apache服务,才可以生效
php版本高于5.3(默认开启PDO)
1.找到需要开启的pdo数据库支持选项,例如开启MYSQL支持,去掉extension=php_pdo_mysql.dll前面的注释
2.重启apache服务,才可以生效
如果按照步骤操作之后仍然不能使用PDO,可能是为什么?
1.可能是php的ext文件夹中没有对应的扩展文件。
2.可能是php.ini中的配置文件目录没有设置或者设置失效,路径选项extension_dir
3.可能是ext文件夹中的dll扩展文件版本不对,或者文件错误
4.环境崩溃,重装软件。
数据库抽象层很多为什么选择PDO?
1.made in china 中国制造
2.使用模块化形式添加到系统中,效率高
3.官方指定使用PDO
4.在高版本的PHP默认开启PDO。
一. PDO:
1.操作步骤
try{
初始化连接一个pdo
$dsn = 'mysql:host=连接地址;dbname=数据库';
$pdo=new PDO($dsn,用户名,密码);
设置字符集 (仅在学习中使用, 实际操作中不可用,会影响效率)
$pdo->exec("SET NAMES utf8");
获取数据库句柄上一次操作想点的sqlstate
$pdo->errorCode();
获取跟上一次语句句柄操作相关的扩展错误信息
$pdo->errorInfo();
准备sql语句
$sql= sql语句
执行sql
$result=$pdo->query($sql); 执行sql语句,返回结果集.有返回结果集时使用如: 查询时使用
$result=$pdo->exec($sql); 执行sql语句,返回受影响的行数,失败默认返回false.无返回结果集时使用如:增删改
处理结果
如果是增删改可以使用if else 判断result是否成功即可
当进行删除和插入操作时 $reuslt 会返回0或1
如果是查询语句可以使用foreach进行遍历结果集, 但是不推荐使用
$result -> fetch(指定参数);获取一条以及
$result -> fetchAll(指定参数);获取所有记录集
$result -> fetchColumn();获取查询结果中下一行的mou'yi'li
指定参数:
PDO::FETCH_ASSOC
让fetch()和fetchall()方法返回一个关联数组,数组的键是数据库的列名
PDO::FETCH_NUM
让fetch()和fetchall()方法返回一个键为数字的数组.数组的键是数据库列在查询结果中的索引
PDO::FETCH_BOTH
让fetch()和fetchall()方法返回一个既有键为列名又有键为数字的数组.这等于把PDO::FETCH_ASSOC和PDO::FETCH_NUM合并
PDO::FETCH_OBJ
让fetch()和fetchall()方法返回一个对象,对象的属性是数据库的列名.
......更多的看手册
$pdo -> lastInsertId();返回上次插入操作,主键列类型是自增的最后的自增ID
事务机制
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);关闭自动提交机制
$pdo->beginTransaction(); 开启事务机制
$pdo->commit(); 提交事务;
$pdo->rollBack();回滚事务;
关闭连接
$pdo = null;
}catch(PDOException $e){
判断是否连接成功
获取pdo自动抛出的异常对象
echo $e->getMessage();
}
插入例子:
# 准备连接语句
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
# 连接pdo
$pdo = new PDO($dsn,'root','');
# 设置连接字符集, 只在学习中使用, 影响效率
$pdo->exec('set name utf8');
# 关闭自动提交
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
# 开启事务机制
$pdo ->beginTransaction();
# 准备sql语句
$sql= "insert into test(content,created) VALUES ('adsfdsa','".time()."')";
# exec默认执行失败会返回false
$result = $pdo->exec($sql);
# 执行语句
if($result > 0){
echo $pdo->lastInsertId();
$pdo->commit();
}else {
$pdo->rollBack();
}
# 关闭连接
$pdo = null;
查询例子:
# 准备连接语句
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
# 连接pdo
$pdo = new PDO($dsn,'root','');
# 设置连接字符集, 只在学习中使用, 影响效率
$pdo->exec('set name utf8');
# 准备sql语句
$sql= "select * from test";
# 执行sql
$result = $pdo->query($sql);
# 处理结果
$arr = $result->fetchAll();
# 关闭连接
$pdo = null;
二. PDO预处理机制:
1.操作步骤
1. 激活句柄连接pdo
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
$pdo = new PDO($dsn,'roo','');
事务: 关闭自动提交机制
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
开启事务机制
$pdo->beginTransaction();
2. 激活pdo预处理,执行sql
$stmt = $pdo->prepare(sql语语句); sql语句中可以使用: 或?作为占位符 如: select * from test id=?/id=:id
3.绑定参数
启动预处理后可以通过, 绑定参数, 执行语句来操作 也可以如下一步直接在执行中使用数组进行绑定参数
$uid=5;
执行办法1: $stmt->bindParam(':id',$uid,指定数据类型);
数据类型值得是数据库类型,常用的有:
PDO::PRAM_BOOL
PDO::PRAM_NULL
PDO::PRAM_INT
PDO::PRAM_STR (默认值)
....更多的看手册
$stmt->execute();
也可以使用bindvalue()进行参数绑定
$stmt->bindvalue(':id',$uid,PDO::PARAM_INT)
bindParam和bindValue的区别
PDOStatement::bindParam不能绑定常量,而bindValue可以绑定常量
如 :
$stm->bindParam(":sex",$sex); //正确 $stm->bindParam(":sex","female"); //错误
$stm->bindValue(":sex",$sex); //正确 $stm->bindValue(":sex","female"); //正确
注意:
bindParam 变量被以引用方式绑定到点位符上,
而且仅仅当调用PDOStatement::execute()时才会去计算具体被绑定变量在PDOStatement::execute()被调用时的值
执行办法2: $stmt->execute(array(":占位符'=>'具体值')"); 直接在执行时使用数组进行绑定参数
4.判断结果, 得到结果集
判断对行的影响
if($stmt->rowCount){
如果需要绑定查询出的结果列则使用bindColumn如:
$stmt->bindColumn(1,$id);
$stmt->bindColumn(2,$name);
$stmt->bindColumn(3,$age);
处理结果集的多重方式
1.$result = $stmt->fetchAll(PDO::FETCH_ASSOC);直接得到所有的结果集
2.while($stmt->fetch(PDO::FETCH_ASSOC)){
如果绑定了查询出的列可以使用
echo $id.'----'.$name.'----'.$age.'<br />';
如果没有绑定,可以直接在while中给结果集赋值得到结果集
}
事务: 提交数据
$pdo->commit();
}else{
事务: 回滚
$pdo->rollback();
echo '操作失败';
}
事务: 开启自动提交机制
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
2.例子:
①:按照ID查询出结果的例子, 查询一条数据
查询条件绑定方式, 使用?作为占位符的绑定方式
结果绑定方式使用bindColumn逐条绑定
try{
# 连接MySQL 激活pdo
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
$pdo = new PDO($dsn, 'root', '');
# 准备预处理机制 使用?作为占位符
$stmt = $pdo->prepare('select * from test where id=?');
# 绑定参数 使变量和占位符之间进行连接
$stmt->bindParam(1,$uid);
# 为绑定的参数进行赋值
$uid = 50;
# 执行sql
$stmt->execute();
# 判断受影响的行数
if($stmt->rowCount() >= 1){
# 绑定查询出的列 变量不必按照数据库列名称命名
$stmt->bindColumn(1,$id); # 第几列值由序号决定,和变量无关
$stmt->bindColumn(2,$content);
$stmt->bindColumn(3,$created);
# 遍历结果集 如果是查询单条数据,没有必要进行while循环
while ($stmt->fetch(PDO::FETCH_ASSOC)){
# 输出之前绑定的查询出的列
echo 'ID: '. $id;
echo '<br>内容: '. $content;
echo '<br>创建时间: '. $created;
}
}else {
echo '查询失败';
}
}catch(PDOException $e){
echo $e->getMessage();
}
按照条件查询多条数据的简易办法:
try{
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
$pdo = new PDO($dsn,'root','');
$stmt = $pdo->prepare('select * from test where id >?');
$stmt->bindParam(1,$id);
$id=1;
$stmt->execute();
if($stmt->rowCount()) {
$resutl = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}catch (PDOException $e){
echo $e->getMessage();
}
②使用 : 作为占位符,绑定:id.使用fetch得到所有结果集进行循环得到所有结果集
如果使用fetchALl获取结果集的话, 就不必进行while循环
try {
# 激活句柄 连接MySQL
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
$pdo = new PDO($dsn, 'root', '');
# 激活预处理机制
$stmt = $pdo->prepare('select * from test where id>:id');
# 绑定参数
$stmt->bindParam(':id', $id);
$id = 1;
# 执行语句
$stmt->execute();
# 判断结果
if ($stmt->rowCount()) {
while ($arr = $stmt->fetch(PDO::FETCH_ASSOC)) {
var_dump($arr);
echo '<hr>';
}
} else {
echo '查询失败';
}
}catch (Exception $e){
echo $e->getMessage();
}
③最佳查询方式[力推]
使用:作为占位符查询,使用fetchAll一次得到所有结果集
try {
# 激活句柄 连接MySQL
$dsn = 'mysql:host=127.0.0.1;dbname=curl';
$pdo = new PDO($dsn, 'root', '');
# 启用预处理机制
$stmt = $pdo->prepare('select * from test where id > :id');
# 执行sql 同时使用数组绑定条件
$stmt->execute(array(':id'=>16));
# 判断是否查询成功
if($stmt->rowCount()){
# 得到结果集
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
}else {
echo '查询失败';
}
}catch (PDOException $e){
echo $e->getMessage();
}
④事务机制 : 简单的事务机制
try{
# 句柄
$dsn = 'mysql:host = 127.0.0.1; dbname=curl';
$pdo = new PDO($dsn,'root','');
# 关闭自动提交
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
#开启事务机制
$pdo->beginTransaction();
# 处理第一条数据
$stmt = $pdo->prepare("update test set content=500 where id=:id");
$result = $stmt->execute(array(':id'=>50));
# 处理第二条数据
$stmt1 = $pdo->prepare('update test set content=500 where id=:id');
$result1 = $stmt1->execute(array(':id'=>51));
# 判断结果
if($result && $result1){
$pdo->commit();
}else {
$pdo->rollBack();
}
# 开启自动提交机制
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
}catch (PDOException $e){
echo $e->getMessage();
}