
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マスターの知恵ブログ
コメント