11、PHP PDO中bindParam()和bindValue()方法的区别

阅读() @2018-07-15 14:13:35

bindParam()和bindValue()的用法非常类似,唯一的区别就是前者必须用一个PHP变量绑定参数,而后者既可以使用变量也可以使用具体的值。

写法如下:

$result = $pdo->prepare("insert into member set name=:name,age=:age");

$name = "jack";

$result->bindParam(":name",$name);//正确

$result->bindParam(":name","jack");//错误

$result->bindValue(":name",$name);//正确

$result->bindValue(":name","jack");//正确

存储过程执行过后的结果可以直接反映到变量上,对于那些内存中的大数据块参数,处于性能的考虑,可以优先使用前者

另外,foreach和bindParam()不能一块使用,但是可以和bindValue()一起使用,具体区别如下:

1、foreach和bindParam()结合使用:

$message = array('blogurl'=>'zymseo.com','subject'=>'SEO,JavaScript,PHP');

$pdo = new PDO("mysql:host=localhost;dbname=list","list","list");
$query = "insert into member set blogurl=:blogurl,subject=:subject";
$result = $pdo->prepare($query);
foreach($message as $key=>$value){
	$result->bindParam($key,$value);
}
$result->execute();

如果按照一般的思维来看,最后插入到数据库中的结果一定是:

blogurl'=>'zymseo.com','subject'=>'SEO,JavaScript,PHP'

但是,实际结果是这样:

foreach和bindParam()结合使用的结果

2、foreach和bindValue()结合使用:

$message = array('blogurl'=>'zymseo.com','subject'=>'SEO,JavaScript,PHP');

$pdo = new PDO("mysql:host=localhost;dbname=list","list","list");
$query = "insert into member set blogurl=:blogurl,subject=:subject";
$result = $pdo->prepare($query);
foreach($message as $key=>$value){
	$result->bindValue($key,$value);
}
$result->execute();

数据库记录如下:

foreach和bindValue()结合使用的结果

出现这种情况的原因就是bindParam和bindValue的不同之处, bindParam要求第二个参数是一个引用变量(reference)。

我们把foreach和bindParam()结合使用的那段代码拆分来看一下:

foreach($message as $key=>$value){
	$result->bindParam($key,$value);
}

相当于:

//第一次循环
$value = $bind_params[":blogurl"];
$result->bindParam(":blogurl", &$value); //此时, :blogurl是对$value变量的引用
 
//第二次循环
$value = $bind_params[":subject"]; //oops! $value被覆盖成了:subject的值
$result->bindParam(":subject", &$value);

所以, 在使用bindParam的时候, 尤其要注意和foreach联合使用的这个陷阱. 那么正确的作法呢?

1、不要使用foreach, 而是手动赋值:

$result->bindParam(":blogurl",$message['blogurl']);
$result->bindParam(":subject",$message['subject']);
$result->execute();

结果如下:

fbindParam()手动赋值

2、如果嫌手动复制太麻烦,可以考虑使用bindValue()方法,上面的代码已经证明它可以和foreach结合使用。

微信二维码
锐壳主机