【问题标题】:MySQL where in (array) [duplicate]MySQL在哪里(数组)[重复]
【发布时间】:2014-01-23 06:23:54
【问题描述】:
function delete_group($db) {
    $ids = Parameters::get('ids');
    $ids = implode(',', $ids); // now a string like '5,6,7'.
    add_to_log($ids);
    try {
        $stmt = $db->prepare("DELETE FROM mytable WHERE id IN (:ids)");
        $stmt->bindParam(':ids', $ids, PDO::PARAM_STR);
        $stmt->execute();
        response('success', 'success', NULL);
    }
    catch (PDOException $e) {
        response('error', 'Delete group failed.', NULL);
    }
}

此代码不起作用:仅删除了第一行。但是如果我这样做了

$stmt = $db->prepare("DELETE FROM mytable WHERE id IN ($ids)");

相反(只需插入字符串),它可以工作,尽管代码存在 SQL 注入安全问题。如何使其工作并保持安全?

【问题讨论】:

  • 你不能那样做。您需要单独绑定它们; SQL 绑定参数不是任意变量插值/连接,而是在接受的地方传递的单个值。
  • 如果我没记错的话,PHP PDO 不支持 WHERE IN 用于准备好的语句。您必须做一些额外的工作来设置它(根据数组的大小创建 X ? 参数或在数组上执行 implode())。

标签: php mysql pdo sql-in


【解决方案1】:
$ids = Parameters::get('ids');
$ids = array_map('intval', $ids);
$ids = implode(',', $ids);

现在您不必担心注射了。

【讨论】:

  • 这是对上述两个问题的最佳答案。
  • @noober 这可能是一个简短的解决方案,但它仅对整数 ID 有效。对于字符串值也可以这样做,但不建议在更大的查询中混合绑定参数和转义字符串。即使行数显着增加,准备好的语句中的绑定参数也是公认的最佳实践。
  • @MichaelBerkowski 从未见过非整数 ID。
  • @noober 这并不意味着它们不存在,或者 IN () 子句仅用于 id PK 列。
  • 因为评论是“//现在是像'5,6,7'这样的字符串。”我将假设它们是整数。
猜你喜欢
  • 2014-02-08
  • 2012-03-15
  • 1970-01-01
  • 2021-01-27
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 2013-07-30
相关资源
最近更新 更多