🐱

SQLのIN区でプレースホルダーを指定する

2025/01/12に公開

PHPなどでSQLを使う場合、SQLインジェクションを防ぐためにSQLをエスケープ(無害化)する必要があります。
そんな時使われるのが、次のような「プレースホルダー」を使ったprepare処理。

$sql = "SELECT * FROM hoge WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$id]);

このように、SQLの中にプレースホルダーを指定しておくことで、SQLインジェクションを防ぐことができます。

IN区のプレースホルダーではまった

今回、SQLの「IN」を使って複数の値にヒットしたレコードを取得したいと思いました。

SELECT * FROM hoge WHERE id IN (1, 2, 3);

で、これをプレースホルダーで処理しようと思ったのですが、なかなかうまくヒットしてくれません。結論としては「?」が値の数だけ必要でした。

SELECT * FROM hoge WHERE id IN (?, ?, ?);
$stmt = $pdo->prepare($sql);
$stmt->execute([1, 2, 3]);

そこで、渡したい値を配列として準備し、その件数を使って「?」の数を算出します。

$placeholders = array_fill(0, count($value), '?');
$sql = 'SELECT * FROM hoge WHERE id IN (' . implode(',', $placeholders) . ')';
$post = $db->exec($sql, $value);

これで、IN区に渡したい値を配列として渡すことができました。

Discussion