给定一个ids数组$galleries = array(1,2,5),我想有一个SQL查询,在它的WHERE子句中使用数组的值,如:
SELECT *
FROM galleries
WHERE id = /* values of array $galleries... eg. (1 || 2 || 5) */
我如何生成这个查询字符串与MySQL使用?
给定一个ids数组$galleries = array(1,2,5),我想有一个SQL查询,在它的WHERE子句中使用数组的值,如:
SELECT *
FROM galleries
WHERE id = /* values of array $galleries... eg. (1 || 2 || 5) */
我如何生成这个查询字符串与MySQL使用?
当前回答
因为最初的问题涉及到一个数字数组,而我使用的是一个字符串数组,我无法使给定的例子工作。
我发现每个字符串都需要封装在单引号中才能使用in()函数。
这是我的解决方案
foreach($status as $status_a) {
$status_sql[] = '\''.$status_a.'\'';
}
$status = implode(',',$status_sql);
$sql = mysql_query("SELECT * FROM table WHERE id IN ($status)");
正如您所看到的,第一个函数用单引号(\')包装每个数组变量,然后内爆数组。
注意:$status在SQL语句中没有单引号。
可能有更好的方式添加引号,但这是可行的。
其他回答
如果正确筛选输入数组,我们可以使用这个"WHERE id IN"子句。就像这样:
$galleries = array();
foreach ($_REQUEST['gallery_id'] as $key => $val) {
$galleries[$key] = filter_var($val, FILTER_SANITIZE_NUMBER_INT);
}
如下面的例子所示:
$galleryIds = implode(',', $galleries);
也就是说,现在你应该安全地使用$query = "SELECT * FROM galleries WHERE id IN ({$galleryIds})";
下面是我使用的方法,对其他数据使用带有命名占位符的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);
Use:
select id from galleries where id in (1, 2, 5);
一个简单的for每个循环将工作。
Flavius/AvatarKava的方法更好,但要确保数组值中没有逗号。
对于带有转义函数的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);
正如Flavius Stef的回答,你可以使用intval()来确保所有id都是int值:
$ids = join(',', array_map('intval', $galleries));
$sql = "SELECT * FROM galleries WHERE id IN ($ids)";