msgbartop
PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 – 左手代码 右手诗
msgbarbottom

16 Oct 12 PDOStatement::bindParam的一个陷阱

废话不多说, 直接看代码:

<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', "test");

$query = <<<QUERY
  INSERT INTO `user` (`username`, `password`) VALUES (:username, :password);
QUERY;
$statement = $dbh->prepare($query);

$bind_params = array(':username' => "laruence", ':password' => "weibo");
foreach( $bind_params as $key => $value ){
    $statement->bindParam($key, $value);
}
$statement->execute();

请问, 最终执行的SQL语句是什么, 上面的代码是否有什么问题?

Okey, 我想大部分同学会认为, 最终执行的SQL是:

INSERT INTO `user` (`username`, `password`) VALUES ("laruence", "weibo");

但是, 可惜的是, 你错了, 最终执行的SQL是:

INSERT INTO `user` (`username`, `password`) VALUES ("weibo", "weibo");

是不是很大的一个坑呢?

—— 如果你想自己找到原因, 那么就不要继续往下读了———

这个问题, 来自今天的一个Bug报告: #63281

究其原因, 也就是bindParam和bindValue的不同之处, bindParam要求第二个参数是一个引用变量(reference).

让我们把上面的代码的foreach拆开, 也就是这个foreach:

<?php
foreach( $bind_params as $key => $value ){
    $statement->bindParam($key, $value);
}

相当于:

<?php
//第一次循环
$value = $bind_params[":username"];
$statement->bindParam(":username", &$value); //此时, :username是对$value变量的引用

//第二次循环
$value = $bind_params[":password"]; //oops! $value被覆盖成了:password的值
$statement->bindParam(":password", &$value);

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

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

<?php
$statement->bindParam(":username", $bind_params[":username"]); //$value是引用变量了
$statement->bindParam(":password", $bind_params[":password"]);

2. 使用bindValue代替bindParam, 或者直接在execute中传递整个参数数组.

3. 使用foreach和reference(不推荐, 原因参看:微博)

<?php
foreach( $bind_params as $key => &$value ) { //注意这里
    $statement->bindParam($key, $value);
}

最后, 展开了说, 对于要求参数是引用, 并且有滞后处理的函数, 都要在使用foreach的时候, 谨慎!


分享到:



Related Posts:

Tags: , , , ,

53 Responses to “PDOStatement::bindParam的一个陷阱”

Pages: [2] 1 » Show All

  1. get adult toys online |

    Sexy lingerie when sold at wholesale rates is a very lucrative offer for any consumer.

    You would undoubtedly enjoy an enhanced charm with its lovely pink
    bowknot. The apparel industry in Australia is doing well internationally and the
    Aussie made fashion attire is now getting popular
    among international fashion freaks.

    Feel free to visit my blog post; get adult toys online

  2. gao |

    非常感谢分享,解决了我的一个大问题

  3. kaola |

    以前确实遇到过这个坑..

Pages: [2] 1 » Show All

Leave a Reply

*