bindValueとbindParamの違いについて。
bindValue
は値をパラメータにバインドするため、値を入れても変数を入れてもOK。
bindParam
は変数名に指定されたパラメータをバインドする。
PR
PDOStatement::bindValue — 値をパラメータにバインドする
基本的な動作は、こちらが素直です。どういうことかというと、bindValueメソッドが実行されると、その時点で、バインドされる値が確定します。
下のコードだと、150とredという値が、bindValueされる時点で確定するということです。言い換えると、executeされる前に値が確定するのです。
$calories = 150; $colour = 'red'; $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'); $sth->bindValue(':calories', $calories, PDO::PARAM_INT); $sth->bindValue(':colour', $colour, PDO::PARAM_STR); $sth->execute();
PDOStatement::bindParam — 指定された変数名にパラメータをバインドする
これに対して、bindParamは、値が確定するタイミングが、bindValueよりも遅くなります。
どういうことかというと、executeされるまでは、値を参照しているにすぎないのです。つまり、bindParamしても、値は確定していない。言い換えると、参照している変数の中身が変わると、別の値がバインドされる可能性があるということです。
これは、bindParamをループ内で使用すると不具合となって表れます。
//これは動かない。なぜなら、$valの値が上書きされてしまうから。 This will fail ($val by value, because bindParam needs &$variable): <?php foreach ($params as $key => $val) { $sth->bindParam($key, $val); } ?> //これは上手く動く。なぜなら、参照を渡しているから。 This works ($val by reference): <?php foreach ($params as $key => &$val) { $sth->bindParam($key, $val); } ?>
参考:
PHP: PDOStatement::bindValue – Manual
PHP: PDOStatement::bindParam – Manual
【PDO】bindParamとbindValueの違い【PHP】 | WEBマスターの知恵ブログ
コメント