Edited at

PHP bindParam()の落とし穴とbindValue()メモ

恥ずかしながらあまり意識したことがなかったのでメモ。


bindParam()

基本的な使い方は以下のような感じ。

プレースホルダに変数内の値をバインドする。

$sql = 'SELECT name, calories

FROM fruit
WHERE calories < :PARAM'
;
$sth = $dbh->prepare($sql);

$param = 150;
$sth->bindParam(':PARAM', $param, PDO::PARAM_INT);

$sth->execute(); // :PARAM には150がバインドされる

ここでの変数$paramは、$param内の値がバインドされるわけではありません。

ここでがバインドされるのは$param参照値です。

そのため、実際に発行されるSQLでは、$sth->execute()が実行されたとき、$paramに格納されている値が採用されて実行されます。

つまり、以下のように参照値をバインドした後に値を変えた場合、後で代入された値が使用されます。

$sql = 'SELECT name, calories

FROM fruit
WHERE calories < :PARAM'
;
$sth = $dbh->prepare($sql);

$param = 150;
$sth->bindParam(':PARAM', $param, PDO::PARAM_INT);
$param = 200;

$sth->execute(); // :PARAM には200がバインドされる

意識していないと、パラメータが期待していない値でSQLを発行してしまう場合があります。


bindValue()

一方、bindValue()は、変数内の値をバインドします。

$sql = 'SELECT name, calories

FROM fruit
WHERE calories < :PARAM'
;
$sth = $dbh->prepare($sql);

$param = 150;
$sth->bindValue(':PARAM', $param, PDO::PARAM_INT);
$param = 200;

$sth->execute(); // :PARAM には150がバインドされる