1.PDO预处理Prepare
预处理语句Prepare是PDO提供的一种DB操作方式。
Prepare语句允许用户在“设置SQL语句”与“执行SQL语句”之间,进行参数的注入与提取操作。
Prepare方法的语言逻辑与正常的PDO访问相同,但正常的PDO访问是直接将参数写死的。
Prepare方法通过在“设置SQL语句”与“执行SQL语句”之间,加入“预处理SQL语句”和“处理SQL参数”程序,
可以更好的控制参数、灵活查询以及防止SQL注入等。
相关方法:
⑴ prepare()和execute(),此两种方法本质是将PDO中的“exec()”方法拆分为两步
⑵ bindValue(),该方法作用在于将 execute()方法的传参方式进一步灵活
⑶ bindColumn(),该方法作用在于将预处理后的执行结果解析呈现。
2.prepare()方法和execute()方法
prepare()方法是“预处理SQL语句”的方法,能够让PDO预先处理“半成品”的SQL语句,
并生成一个“PDOStatementObject”(PDOSO)类型的结果。
execute()方法是提供给 PDOSO 类型对象去执行的“成品”SQL语句的方法,
并生成一个“PDOStatementObject”类型的结果。
说明:
⑴ 需要PDO通过prepare()预处理的“半成品”SQL语句中,使用“?”问号作为占位符,
表示待传参的参数;
⑵ prepare()方法必须且只能处理“半成品”的SQL语句,如果是完整的SQL语句则使用“exec()”方法执行;
⑶ execute()方法允许一个数组作为参数,并将参数带入到预处理的SQL语句中,
而且会将结果存放到 PDOSO 类型对象中;
⑷ PDOSO对象在预处理的不同阶段有着不同的含义!!!不能混淆,必须根据上下文进行判断。
语法:
$sql = "insert into nameList values(?,?,?,?)";
$pdoso = $pdo -> prepare($sql);
echo $pdoso -> execute(array('Marc','boy',25,'111111'));
3.bindValue()方法
bindValue()方法是提供给PDO预处理之后得到的 PDOSO 对象使用的方法。
用于给“半成品”的SQL语句传值。
语法:$pdoso -> bindValue(index,value);
说明:
⑴ 第一个参数 index 表示给SQL语句中的第几个参数传值,第一个为“1”,依次类推;
⑵ 第二个参数 value 表示给SQL语句中对应参数的具体赋值;
⑶ bindValue一次只能绑定一个参数进行传值,如有多个则需要执行多次。
代码示例:
- <?php
- // echo '<pre>';
- require_once "20210111singleton.php";
- $pdo1 -> exec('set names utf8'); //辅助设置
- $sql = "update nameList set sex=?,age=? where name='Wendy'";
- $pdoso = $pdo1->prepare($sql);
- // 在 prepare()方法和 execute()方法之间使用 bindValue对SQL中的“?”赋值。
- $pdoso -> bindValue(1,'girl');
- $pdoso -> bindValue(2,21);
- // execute()方法可以没有参数,表示直接执行PDOSO对象所代表的的SQL语句。
- $pdoso->execute();
- ?>
4.bindColumn()方法
bindColumn()方法允许将执行结果的一列数据绑定到一个指定的对象上。
本方法需要在“execute()”执行结束后再执行。
语法:$pdoso -> bindColumn(index,$变量名);
说明:
⑴ 第一个参数“index”表示结果中的第几列数据,第一列为“1”,依次类推;
⑵ 第二个参数表示将获取的数据赋值给哪个变量;
⑶ 该方法一次只能绑定一列数据给指定的一个变量,如果绑定多列数据,则需执行多次。
代码示例:
- <?php
- echo '<pre>';
- require_once "20210111singleton.php";
- $pdo1 -> exec('set names utf8'); //辅助设置
- $sql = "select * from nameList where 1";
- $pdoso = $pdo1->prepare($sql);
- $pdoso->execute();
- //将执行结果绑定到指定的变量
- $pdoso -> bindColumn(1,$uName);
- $pdoso -> bindColumn(2,$uSex);
- $res1 = [];
- // 将执行结果解析并输出
- while($row=$pdoso->fetch(PDO::FETCH_COLUMN)){
- $res1["$uName"]=$uSex;
- }
- print_r ($res1);
- // 或通过 for 循环解析
- $res2 = [];
- for($j=0;$row=$pdoso->fetch(PDO::FETCH_COLUMN);$j++){
- $res2[$j]=array('name'=>$uName,'sex'=>$uSex);
- }
- print_r($res2);
- ?>
5.PDO事务处理
事件:一条执行语句就是一个事件,如prepare预处理时执行的execute语句。
事务:多个事件组成的结构,主要特点:多个事件同时执行、发生异常后回滚至执行前状态。
注意:
⑴ 整个事务操作必须放到“try...catch”中,这是因为我们并不能保证执行的事件一定成功。
而对于整个事务而言,任何一个事件的失败都会导致“catch”的触发。
而 catch 的触发就意味着需要将之前做出的所有操作都必须还原。
回滚操作:$pdo -> rollBack();
⑵ 操作语句必须在事务开启之后执行,在事务提交之前停止。
开启事务:$pdo -> beginTransaction();
关闭事务:$pdo -> commit();
⑶ 中文处理方案(避免乱码)。
读取:$pdo -> query("set names utf8");
插入:$pdo -> exec("set names utf8");
代码示例:
数据库连接代码:
- <?php
- class singletonPDO{
- private static $pdo = null; //使用私有静态变量声明单例对象
- public static function getPdo(){
- if(self::$pdo==null){
- try{
- self::$pdo = new PDO("mysql:host=localhost;dbname=dbTest","root","");
- self::$pdo -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
- }catch(PDOException $err){
- echo "数据库连接失败,错误信息:".$err->getMessage();
- }
- }
- return self::$pdo;
- }
- }
- $pdo1 = singletonPDO::getPdo();
-
- // 可以通过“ require''或include'' ”方法,在其他PHP文件中引用这个模板。
- // 为避免重复多次引用,可以使用“ require_once'' ”。
- ?>
事务处理代码:
- <?php
- require_once '20210111singleton.php';
- $pdo1->exec('set names utf8');
- try{
- // 开启事务,所有事件写在事务开启和提交之间
- $pdo1->beginTransaction();
- $sql="update nameList set age=?,password=? where name=?";
- // SQL预处理语句
- $pdoso=$pdo1->prepare($sql);
- $pdoso->execute([23,'123456','Wendy']);
- $pdoso->execute([25,'123456','Lucy']);
- // 提交事务
- $pdo1->commit();
- echo '事务提交成功!数据库已执行更新。';
- }catch(PDOException $err){
- // 设置事务回滚
- $pdo1->rollBack();
- echo '事务提交失败!程序已回滚至初始状态。';
- }
- ?>