PHPのWHERE句で使う「?」の数を動的に作ろう

PHPでは、SQLのWHERE句で位置パラメータを使う場合こう書きますよね。

PHP
$id = 123;

$sql = 'SELECT * FROM test_table WHERE id = ?';

$stmt = $this->pdo->prepare($sql);
$stmt->execute($id);
$result = $stmt->fetch(PDO::FETCH_ASSOC);

この「?」(プレースホルダー)を使ったWHERE句、上記の場合は条件を付けるカラムの数が1つで済むのでこれでOKですが、もし

PHP
$ids = [123,456,789,1000,1033,345,184,2777,493];

と配列に入っていて、上記の場合は数が数えればわかりますが、配列自体が動的に数が変わってしまう等

数がよくわからない場合はどうすればいいでしょうか?

目次

implodeとarray_fillの合わせ技

前回の記事の最後に触れたimplodeを使います。

また、array_fillという関数も使います。

  • implode:指定した文字列で配列のvalueを連結する
  • array_fill:指定した文字列で埋めた配列を生成する

つまり、

STEP
array_fillで欲しい個数分の「?」を生成する

これで「????????」等のプレースホルダーが出来ます。

STEP
implodeで①の配列を「,」で連結する

これで「?,?,?,?,?,?,?,?」のようにプレースホルダーに対して「,」を挿入することが出来ます。

という手順を踏めば動的にWHERE句でほしい分の「?」を作ることが出来ます。

PHP
$ids = [123,456,789,1000,1033,345,184,2777,493];

$placeholders = implode(
    ',',
    array_fill(0, count($ids), '?')
);

$sql = 'SELECT * FROM test_table '
$sql .= 'WHERE id IN (' $placeholders ')';

$stmt = $this->pdo->prepare($sql);
$stmt->execute($ids);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

これでWHERE句でほしい個数分の「?」(プレースホルダー)が出来たはずです。

おまけ:array_merge

WHERE句でもう1フィールドWHERE句がほしいなぁ・・・

それもまた配列を使いたいという時はarray_mergeを使います。

PHP
...
$names = ['taro', 'hanako'];

$sql .= " AND test_name IN (?, ?)";

$where = array_merge($ids, $names);

$stmt = $this->pdo->prepare($sql);
$stmt->execute($where);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

mergeという文字通り、array_mergeは配列同士を結合します。

なので、executeする時に困りません。

PHP
$stmt->execute($ids,$names);

executeは引数を1つしかとらないので、2つ入れると必ずエラーになります。

参考になれば嬉しいです。

  • URLをコピーしました!
目次