PHP使用PDO预处理
1.什么是预处理
预处理是指将SQL语句的编译与执行分离,它常常用与执行多条相似度很高的SQL语句(参数不同)。有点是执行效率跟高,防止SQL注入也更安全。
2.非预处理过程
假设数据库中有一张结构如图
现在我们向表中插入三条条记录,不适用预处理的做法应该是这样的
1 <?php 2 $dsn="mysql:host=127.0.0.1;dbname=example"; 3 $user="root"; 4 $password=''; 5 try 6 { 7 $pdo=new PDO($dsn,$user,$password); 8 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 9 10 $pdo->exec("INSERT INTO student VALUES(null,'one',18,'1111111')"); 11 $pdo->exec("INSERT INTO student VALUES(null,'two',19,'2222222')"); 12 $pdo->exec("INSERT INTO student VALUES(null,'three',20,'3333333')"); 13 } 14 catch(PDOException $e) 15 { 16 echo $e->getMessage(); 17 } 18 ?>
在执行数据库操作时过程是这样的:
编译10行SQL语句-->执行10行语句-->编译11行SQL语句-->执行11行语句-->编译12行SQL语句-->执行12行语句。
但是观察可以发现这三条语句的相似度是非常高的,它们之间的不同仅仅是传递的参数不同而已。那么数据库执行操作时重复编译多次相同的SQL语句是非常耗费资源且不必要的。
3.PDO预处理
编译与执行分离
PDO提供给我们一个方法,可以将SQL语句送到数据库进行编译,而不执行。参数部分可以用占位符代替。
1 $pdo->prepare("INSERT INTO stduent VALUES (null,:name,:age,:address)");//关联占位,必须以:开头接 2 $pdo->prepare("INSERT INTO stduent VALUES (null,?,?,?)");//索引占位
该方法返回一个PDOStatement对象,接下来如果要执行就要调用PDOStatement里的方法
$pdostatement->execute();
传入参数
在执行时,我们需要向编译好的SQL语句传递参数,以关联数组或者索引数组的方式
1 $pdostatement->execute(array('name'=>'eee','age'=>23,'address'=>'assdada')); 2 $pdostatement->execute(array('eee',23,'assdada'));
注意传参方式必须和设置占位符的方式一致
预处理执行
经过改进之后,执行过程如下所示
1 <?php 2 $dsn="mysql:host=127.0.0.1;dbname=example"; 3 $user="root"; 4 $password=''; 5 try 6 { 7 $pdo=new PDO($dsn,$user,$password); 8 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 9 10 $pdostatement=$pdo->prepare("INSERT INTO student VALUES (null,:name,:age,:address)");//关联占位,必须以:开头接 11 12 $pdostatement->execute(array('name'=>'eee','age'=>23,'address'=>'assdada')); 13 $pdostatement->execute(array('name'=>'fff','age'=>24,'address'=>'assdada')); 14 $pdostatement->execute(array('name'=>'ggg','age'=>25,'address'=>'assdada')); 15 $pdostatement->execute(array('name'=>'hhh','age'=>26,'address'=>'assdada')); 16 17 } 18 catch(PDOException $e) 19 { 20 echo $e->getMessage(); 21 } 22 ?>
成功插入这样做即方便又安全,执行效率还高。