给定一个ids数组$galleries = array(1,2,5),我想有一个SQL查询,在它的WHERE子句中使用数组的值,如:

SELECT *
FROM galleries
WHERE id = /* values of array $galleries... eg. (1 || 2 || 5) */

我如何生成这个查询字符串与MySQL使用?


当前回答

Col. Shrapnel的SafeMySQL PHP库在其参数化查询中提供了类型提示占位符,并包括了两个用于处理数组的方便占位符。?a占位符将数组展开为逗号分隔的转义字符串列表*。

例如:

$someArray = [1, 2, 5];
$galleries = $db->getAll("SELECT * FROM galleries WHERE id IN (?a)", $someArray);

*请注意,由于MySQL执行自动类型强制,SafeMySQL将上面的id转换为字符串并不重要-您仍然会得到正确的结果。

其他回答

对于带有转义函数的MySQLi:

$ids = array_map(function($a) use($mysqli) { 
    return is_string($a) ? "'".$mysqli->real_escape_string($a)."'" : $a;
  }, $ids);
$ids = join(',', $ids);  
$result = $mysqli->query("SELECT * FROM galleries WHERE id IN ($ids)");

对于带准备语句的PDO:

$qmarks = implode(',', array_fill(0, count($ids), '?'));
$sth = $dbh->prepare("SELECT * FROM galleries WHERE id IN ($qmarks)");
$sth->execute($ids);

假设你事先正确地清理了你的输入……

$matches = implode(',', $galleries);

然后调整你的查询:

SELECT *
FROM galleries
WHERE id IN ( $matches ) 

根据数据集适当地引用值。

小心!此答案包含一个严重的SQL注入漏洞。不要使用这里给出的代码示例,除非确保任何外部输入都被清除。

$ids = join("','",$galleries);   
$sql = "SELECT * FROM galleries WHERE id IN ('$ids')";

更安全。

$galleries = array(1,2,5);
array_walk($galleries , 'intval');
$ids = implode(',', $galleries);
$sql = "SELECT * FROM galleries WHERE id IN ($ids)";

下面是我使用的方法,对其他数据使用带有命名占位符的PDO。为了克服SQL注入,我过滤了数组,只接受整数的值,并拒绝所有其他的值。

$owner_id = 123;
$galleries = array(1,2,5,'abc');

$good_galleries = array_filter($chapter_arr, 'is_numeric');

$sql = "SELECT * FROM galleries WHERE owner=:OWNER_ID AND id IN ($good_galleries)";
$stmt = $dbh->prepare($sql);
$stmt->execute(array(
    "OWNER_ID" => $owner_id,
));

$data = $stmt->fetchAll(PDO::FETCH_ASSOC);