PDOでIN句を使ったらハマった話

PHPはたまーにモンキーパッチを書く程度のエンジニア

for($i = 0;$i < count($val);$i++){  
  $name = ":$key" .  "_$i";
  $bindVal = $val[$i];
  $stmt->bindParam($name, $bindVal);
}

PreparedStatementでIN句に値をバインドするとき、こんな感じで書いていた。そしたら何故か「最後に選択した値」の物しかでず、困っていた。
最初の可能性としては以下の物を考えていた。

  • 入力された値が全部最後に選択した値になっちゃってる
  • パラメータ名が間違ってて、全部同じになっちゃってる

どっちも検証してみたら正常。発行したSQLが確認できれば一番早いんだけど、レンタル鯖だしPDOにそんな機能はないみたいなのでメッチャ困ってた。

で、「そういえばバインドする値の指定って、値を指定してるんじゃなくて変数の参照なんだよな。」と、前にドキュメントちら見したときの記憶がよみがえる。

もしバインドされるタイミングがexecuteをコールした時だったら・・・?てかどっかでそんな書き込みみたような??

$bindValは毎回上書きされてるので、PHPの挙動はどうなってるかわからないけど、同じ参照値で値をゴリゴリ変えてるだけかもしれない。その結果最後の値になるのかもしれない…。

と思って、なぜか余計にかませてた$bindVal = $val[$i]を消して、$val[$i]を直接書いたら普通に動きましたとさ。

for($i = 0;$i < count($val);$i++){  
  $name = ":$key" .  "_$i";
  $stmt->bindParam($name, $val[$i]);
}

こんなものに2時間も頭を悩ませてしまった・・・。お疲れ様でした。