您必须手动构建占位符列表,为每个数组成员添加一个占位符。
<?php
$ids = [1, 2, 3, 7, 8, 9];
$inQuery = str_repeat('?,', count($arr) - 1) . '?'; // gets ?,?,?,?,?,?
$stmt = $db->prepare("SELECT * FROM table WHERE id IN($inQuery)");
$stmt->execute($ids);
$data = $stmt->fetchAll();
Given $inQuery
不接受任何输入并完全由常量值构造(?,
部分),在查询中添加这样的变量是安全的。
如果查询中有其他占位符,您可以使用array_merge()
函数将所有变量连接到一个数组中,以数组的形式添加其他变量,按照它们在查询中出现的顺序:
$arr = [1,2,3];
$in = str_repeat('?,', count($arr) - 1) . '?';
$sql = "SELECT * FROM table WHERE foo=? AND column IN ($in) AND bar=? AND baz=?";
$stmt = $db->prepare($sql);
$params = array_merge([$foo], $arr, [$bar, $baz]);
$stmt->execute($params);
$data = $stmt->fetchAll();
如果您使用命名占位符,代码会稍微复杂一些,因为您必须创建命名占位符的序列,例如:id0,:id1,:id2
。所以代码是:
// other parameters that are going into query
$params = ["foo" => "foo", "bar" => "bar"];
$ids = [1,2,3];
$in = "";
$i = 0; // we are using an external counter
// because the actual array keys could be dangerous
foreach ($ids as $item)
{
$key = ":id".$i++;
$in .= ($in ? "," : "") . $key; // :id0,:id1,:id2
$in_params[$key] = $item; // collecting values into a key-value array
}
$sql = "SELECT * FROM table WHERE foo=:foo AND id IN ($in) AND bar=:bar";
$stmt = $db->prepare($sql);
$stmt->execute(array_merge($params, $in_params)); // just merge two arrays
$data = $stmt->fetchAll();
幸运的是,对于命名占位符,我们不必遵循严格的顺序,因此我们可以按任何顺序合并数组。