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

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

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


当前回答

使用PDO: [1]

$in = join(',', array_fill(0, count($ids), '?'));
$select = <<<SQL
    SELECT *
    FROM galleries
    WHERE id IN ($in);
SQL;
$statement = $pdo->prepare($select);
$statement->execute($ids);

使用MySQLi [2]

$in = join(',', array_fill(0, count($ids), '?'));
$select = <<<SQL
    SELECT *
    FROM galleries
    WHERE id IN ($in);
SQL;
$statement = $mysqli->prepare($select);
$statement->bind_param(str_repeat('i', count($ids)), ...$ids);
$statement->execute();
$result = $statement->get_result();

解释:

使用SQL IN()操作符检查给定列表中是否存在某个值。

通常情况下是这样的:

expr IN (value,...)

我们可以从数组中构建一个表达式放在()中。注意,括号内必须至少有一个值,否则MySQL将返回错误;这相当于确保我们的输入数组至少有一个值。为了防止SQL注入攻击,首先生成一个?为每个输入项创建参数化查询。这里我假设包含id的数组叫做$ids:

$in = join(',', array_fill(0, count($ids), '?'));

$select = <<<SQL
    SELECT *
    FROM galleries
    WHERE id IN ($in);
SQL;

给定一个包含三个元素的输入数组,$select将如下所示:

SELECT *
FROM galleries
WHERE id IN (?, ?, ?)

再次注意这里有一个?对于输入数组中的每个项。然后,我们将使用PDO或MySQLi来准备和执行上面提到的查询。

对字符串使用IN()操作符

由于绑定了参数,所以很容易在字符串和整数之间进行更改。对于PDO,不需要更改;对于MySQLi,如果你需要检查字符串,将str_repeat('i',改为str_repeat('s'。

[1]:为了简洁,我省略了一些错误检查。您需要检查每个数据库方法的常见错误(或设置您的DB驱动程序抛出异常)。

[2]:要求PHP 5.6或更高版本。为了简洁起见,我再次省略了一些错误检查。

其他回答

使用PDO: [1]

$in = join(',', array_fill(0, count($ids), '?'));
$select = <<<SQL
    SELECT *
    FROM galleries
    WHERE id IN ($in);
SQL;
$statement = $pdo->prepare($select);
$statement->execute($ids);

使用MySQLi [2]

$in = join(',', array_fill(0, count($ids), '?'));
$select = <<<SQL
    SELECT *
    FROM galleries
    WHERE id IN ($in);
SQL;
$statement = $mysqli->prepare($select);
$statement->bind_param(str_repeat('i', count($ids)), ...$ids);
$statement->execute();
$result = $statement->get_result();

解释:

使用SQL IN()操作符检查给定列表中是否存在某个值。

通常情况下是这样的:

expr IN (value,...)

我们可以从数组中构建一个表达式放在()中。注意,括号内必须至少有一个值,否则MySQL将返回错误;这相当于确保我们的输入数组至少有一个值。为了防止SQL注入攻击,首先生成一个?为每个输入项创建参数化查询。这里我假设包含id的数组叫做$ids:

$in = join(',', array_fill(0, count($ids), '?'));

$select = <<<SQL
    SELECT *
    FROM galleries
    WHERE id IN ($in);
SQL;

给定一个包含三个元素的输入数组,$select将如下所示:

SELECT *
FROM galleries
WHERE id IN (?, ?, ?)

再次注意这里有一个?对于输入数组中的每个项。然后,我们将使用PDO或MySQLi来准备和执行上面提到的查询。

对字符串使用IN()操作符

由于绑定了参数,所以很容易在字符串和整数之间进行更改。对于PDO,不需要更改;对于MySQLi,如果你需要检查字符串,将str_repeat('i',改为str_repeat('s'。

[1]:为了简洁,我省略了一些错误检查。您需要检查每个数据库方法的常见错误(或设置您的DB驱动程序抛出异常)。

[2]:要求PHP 5.6或更高版本。为了简洁起见,我再次省略了一些错误检查。

所有交易所:

$query = "SELECT * FROM `$table` WHERE `$column` IN(".implode(',',$array).")";

字符串:

$query = "SELECT * FROM `$table` WHERE `$column` IN('".implode("','",$array)."')";

无PDO的安全方法:

$ids = array_filter(array_unique(array_map('intval', (array)$ids)));

if ($ids) {
    $query = 'SELECT * FROM `galleries` WHERE `id` IN ('.implode(',', $ids).');';
}

将$ids变量强制转换为数组 将所有数组值转换为整数 移除重复的值 删除零值 内爆连接所有值到IN选择

正如Flavius Stef的回答,你可以使用intval()来确保所有id都是int值:

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

对于带有转义函数的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);