开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第三阶段:PDO 预处理数据绑定】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/713/detail/12738
PDO 预处理数据绑定
内容介绍:
一、 概念
二、 示例
三、 小结
一、概念
1、目标:掌握PDO关于预处理参数绑定的实现,掌握不同类型数据绑定的实际区别。
2、概念
数据绑定:是指在进行预处理指令定义时使用了占位符,占位符是否为原生不重要,若是原生用索引做一个替换即可。如果用的是优化后的冒号加名字形式,使用关联的冒号加名字的形式即可。为了保证后续执行预处理时能够正确执行,将实际数据替换占位符的过程
(1)数据绑定的方式应该与占位符方式对应
(2)PDOStatement:execute()方法本身就可以实现数据传递和绑定,不需要使用bindValue()或者bindParam()。
(3)PDOStatement:bindValue()和bindParam()在实际运用中有明显区别
二、示例
1、在PDO中,execute本身是可以直接进行数据绑定的,即在参数中增加对应的占位符数据,以数组形式传入。
(1)预处理形式使用原始占位符?
$stmt = $pdo->prepare( 'select * from t_40 where id = ?');
$stmt->execute(array(10));
# 操作where id = ?后,传入一个数组即可。array代表是数组,10代表是替换值,如果有多个元素,顺序放入即可。比如“1”,就传一个“10”,如果有“2”可以传后面值。
代码示例:
<?php
#实例化
$pdo=new PDO('mysql:host=localhost;port=3306;dbname=db _2;charset=utf8 ' , ' root' , 'root ') or die('数据库连接失败! ');
$pre_sql = "select * from t_40 whereid = ?";
# PDO特定预处理参数指令(︰+字符串),更明确
#发送预处理指令
$stmt = $pdo->prepare($pre_sql);
if(!$stmt) die('预处理指令执行失败!');
#执行预处理:绑定参数,可以使用execute方法直接传(数组传)
#索引方式:不需要给下标,直接数字索引即可
#关联方式:需要给定下标
$res = $stmt->execute();
var_dump($res);
如果直接做会产生错误:没有被绑定一个对应的参数。
但是结果拿到的依然是 false,只是系统检测到需要参数但是未能传入参数。
$res = $stmt->execute(array(1));
var_dump($res);
结果显示运行执行成功。说明该1被绑定。
再进行证明:用var_dump();再把数据取出来。所以:
$res = $stmt->execute(array(1));
var_dump($stmt->fetch(PDO ::FETCH_ASSOC));
刷新结果确实拿到了:
如果是array(12)也会有数据
(2)预处理形式使用PDO占位符: +名字
$stmt = $pdo->prepare('select * from t_40 where id = :id ');
$stmt->execute(array( ' :id'=> 10));
# 使用占位符作为数组元素下标
2、PDOStatement:bindValue()和PDOStatement::bindParam()区别
(1)二者都可以实现占位符的数据绑定
(2)形式上的区别:bindValue绑定数据的方式灵活,可以是变量也可以是数据常量;而bindParam只能是变量
(3)本质的区别:因为bindParam绑定的是变量(引用传值),所以如果被绑定的变量发生改变,会直接影响后续execute结果。而bindValue传递的是值,所以对应的外部的一个变量修改后不会影响内部。
#测试bindValue:
$stmt = $pdo->prepare( 'select * from t_40 where id = :id');
$id = 1;
#给它一个变量
$stmt->bindvalue( ' :id' ,$id);
#然后把它绑定进去
for(;$id < 10;$id++){ #绑定之后让id开始变化,每次去拿结果
$stmt->execute();
$row = $stmt->fetch(PDO : : FETCH_ASSOC);
var_dump($row);
echo ‘<br>’
}
结果有九条数据但我们需要查询id为1的。因为传递了一个值,所以无论变量如何改动都不会影响方法内部接收的变量的值。所以需要替换内容:
echo ‘<hr>’
#测试bindParam:
$id = 1;
$stmt->bindParam( ' :id' ,$id);
for( ;$id < 10;$id++){
$stmt->execute(;
$row = $stmt->fetch(PDO :: FETCH_ASSOC) ;
var_dump($row);
echo ‘<br>’
}
此时结果运行发现,每一条数据不一样
说明外部id的改变影响了绑定的参数,因为是每次去执行一个execute()。执行execute()的时候会检测id是否改变。所以bindParam就会检测外部。如果外部改变,内部相应的就会修改。它能够实现绑定的数据随着外部的改变而每次执行execute()的时候影响到内部。
三、小结
1、PDO绑定预处理数据的方式有多种:
PDOStatement::bindValue()/bindParam()/execute()
(1)execute()少调用一个方法,简单。
(2)bindValue()可以直接绑定值。
(3)bindParam()更复杂一点,因为它必须要定义变量再传递值。但是正是因为必须要定义变量再传递值,而有了便捷性。
2、如果数据简单且不需要重复,那么使用bindValue()/execute()都可以。
3、如果数据本身是变化的,而且是有规则(数组遍历出来的结果),那么可以使用bindParam()来节省操作。
也可以使用bindValue,需要将$stmt->bindValue( ' :id' ,$id);放在for循环中,也可以达到这种效果。但是bindParam的效率要比bindValue高