《Php笔记2.2》PDO 安全处理与事务处理
在我们做项目的时候,为了优化项目需要对报错模式,线上与线下进行不同的配置。目的为了提高用户体验,同时为了安全处理需要预处理来防止 SQL 注入。有时我们需要(增删改)作为一个操作单元,要么全成功,要么全失败。比如:用户之间转账、删除某一个用户相关的数据,这些都需要事务处理来操作。
异常处理:优化报错等。
PDO预处理:防止SQL注入,优化效率。
PDO事务处理:将多个操作作为一个单元,全部成功或全部失败。
PDO 异常处理
本课时讲解 PDO 异常处理的作用,以及 PDO 异常处理的设置。
pdoException.php:
1 //默认是不提示的 需要用errorCode() errorInfo() 2 try{ 3 $pdo = new PDO("mysql:host=localhost;dbname=woodk;", "root", "root"); 4 //ATTR_ERRMODE的默认值是:0 5 //$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); 6 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 7 }catch(PDOException $e){ 8 die("数据库连接失败".$e->getMessage()); 9 } 10 $sql = "INSERT INTO stuu VALUE(null, '李凯儿', 20)"; 11 12 try{ 13 $res = $pdo->exec($sql); 14 }catch(PDOException $e){ 15 echo $e->getMessage(); 16 //echo $pdo->errorCode(); 17 //print_r($pdo->errorInfo()); 18 }
PDO 预处理
本课时讲解预处理的工作原理,以及预处理的应用。
pdoPrepare.php: ?号式的预处理语句,3种绑定方式
1 <?php 2 //1.连接数据库 3 try{ 4 $pdo = new PDO("mysql:host=localhost;dbname=woodk", "root", "root"); 5 }catch(PDOException $e){ 6 die('数据库连接失败'.$e->getMessage()); 7 } 8 9 //2.预处理的SQL语句 10 $sql = "INSERT INTO stu(id, name, sex, age) VALUE(?,?,?,?)"; 11 $stmt = $pdo->prepare($sql); 12 13 //?号式的预处理语句 一共有3种绑定方式 14 //3.1 第一种绑定值 15 $stmt->bindValue(1, null); 16 $stmt->bindValue(2, 'test55'); 17 $stmt->bindValue(3, 'w'); 18 $stmt->bindValue(4, 22); 19 20 //3.2 第二种绑定参数 21 /* 22 $stmt->bindParam(1, $id); 23 $stmt->bindParam(2, $name); 24 $stmt->bindParam(3, $sex); 25 $stmt->bindParam(4, $age); 26 $id = null; 27 $name = "test66"; 28 $sex = "m"; 29 $age = 33; 30 */ 31 32 //3.3 第三种数组方式 33 //$stmt->execute(array(null, 'test77', 'm', 22)); 34 35 //4.执行 36 $stmt->execute(); 37 echo $stmt->rowCount();
pdoPrepare2.php: 别名式的预处理语句,也是3种绑定方式
1 <?php 2 //1.连接数据库 3 try{ 4 $pdo = new PDO("mysql:host=localhost;dbname=woodk", "root", "root"); 5 }catch(PDOException $e){ 6 die('数据库连接失败'.$e->getMessage()); 7 } 8 9 //2.预处理的SQL语句 10 $sql = "INSERT INTO stu(id, name, sex, age) VALUE(:id,:name,:sex,:age)"; 11 $stmt = $pdo->prepare($sql); 12 13 //别名式的预处理语句 一共有3种绑定方式 14 //3.1 第一种绑定值 15 $stmt->bindValue("id", null); 16 $stmt->bindValue("name", 'test55'); 17 $stmt->bindValue("sex", 'w'); 18 $stmt->bindValue("age", 22); 19 20 //3.2 第二种绑定参数 21 /* 22 $stmt->bindParam("id", $id); 23 $stmt->bindParam("name", $name); 24 $stmt->bindParam("sex", $sex); 25 $stmt->bindParam("age", $age); 26 $id = null; 27 $name = "test66"; 28 $sex = "m"; 29 $age = 33; 30 */ 31 32 //3.3 第三种数组方式 33 //$stmt->execute(array("id"=>null, "name"=>'test77', "sex"=>'m', "age"=>22)); 34 35 //4.执行 36 $stmt->execute(); 37 echo $stmt->rowCount();
pdoPrepare3.php: 预处理执行,绑定结果的方式
1 <?php 2 3 //采用预处理SQL执行查询,并采用绑定结果方式输出 4 //1.连接数据库 5 try{ 6 $pdo = new PDO("mysql:host=localhost;dbname=woodk", "root", "root"); 7 $pdo->query('set names utf8'); //字符集 8 }catch(PDOException $e){ 9 die('数据库连接失败'.$e->getMessage()); 10 } 11 12 //2.预处理的SQL语句 13 $sql = "SELECT * FROM stu"; 14 $stmt = $pdo->prepare($sql); 15 16 //3.执行 17 $stmt->execute(); 18 19 //预处理:绑定结果的方式 20 $stmt->bindColumn(1, $id); 21 $stmt->bindColumn(2, $name); 22 $stmt->bindColumn("sex", $sex); 23 $stmt->bindColumn("age", $age); 24 25 while($row = $stmt->fetch(PDO::FETCH_COLUMN)){ 26 echo $id.'---'.$name.'---'.$sex.'---'.$age.'<br>'; 27 } 28 //foreach($stmt as $row){ 29 // echo $row['id']."-----".$row['name'].'<br>'; 30 //}
PDO 事务处理
本课时讲解事务处理的应用场合,以及事务处理如何应用。数据表必须是InnoDB类型!(没有注意这一条,害我足足浪费了两个小时调试,sb了。。。)
pdoBeginTransaction.php: 利用PDO::ERRMODE_EXCEPTION,然后try...catch 来操作。
1 <?php 2 3 //采用预处理+事物处理执行SQL操作 4 //1.连接数据库 5 try { 6 $pdo = new PDO("mysql:host=localhost;dbname=woodk", "root", "root"); 7 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 8 } catch (PDOException $e) { 9 die("数据库连接失败".$e->getMessage()); 10 } 11 12 //2.执行数据操作 13 try{ 14 //开启事物 15 $pdo->beginTransaction(); 16 $sql = "INSERT INTO stu(id,name,age) values(?,?,?)"; 17 $stmt = $pdo->prepare($sql); 18 //传入参数 19 $stmt->execute(array(null,"test4",11)); 20 $stmt->execute(array(null,"test5",11)); 21 $stmt->execute(array(null,"test3",11)); 22 23 //提交事物 24 $pdo->commit(); 25 26 }catch(PDOException $e){ 27 die("执行失败".$e->getMessage()); 28 $pdo->rollBack(); 29 }
pdoBeginTransaction2.php: 不用try...catch的办法
1 <?php 2 3 //采用预处理+事务处理执行SQL操作 4 //1.连接数据库 5 try{ 6 $pdo = new PDO("mysql:host=localhost;dbname=woodk","root","root"); 8 }catch(PDOException $e){ 9 die("数据库连接失败".$e->getMessage()); 10 } 11 //2.执行数据操作 12 13 //开启事物 14 $pdo->beginTransaction(); 15 $sql = "insert into stu(id,name,age) values(?,?,?)"; 16 $stmt = $pdo->prepare($sql); 17 $datalist = array( 18 array(null,"test6",11), 19 array(null,"test7",11), 20 array(null,"test3",11) 21 ); 22 $isCommit = true; 23 24 foreach($datalist as $data){ 25 $stmt->execute($data); 26 if($stmt->errorCode()>0){ 27 $pdo->rollBack(); 28 $isCommit = false; 29 break; 30 } 31 } 32 33 if($isCommit){ 34 //提交事物 35 $pdo->commit(); 36 }