【问题标题】:PHP PDO prepared statement IN() array [duplicate]PHP PDO准备好的语句IN()数组[重复]
【发布时间】:2014-03-12 20:40:50
【问题描述】:

来自the PHP Manual

您不能将多个值绑定到单个命名参数,例如 SQL 语句的 IN() 子句。

但是您可以使用问号参数标记来使用多个值吗?还是每次值的数量发生变化时都必须prepare() 一个新语句?

SELECT * FROM `table` WHERE `column` IN(?)

如果允许,你如何使它工作?

编辑:前面提到的两个问题都是关于 named 变量的,手册上说不能绑定到多个参数。我在问问号(匿名)变量。

【问题讨论】:

  • 这个问题经常被问到。 Here's oneand here's another
  • 从多个值中创建一个字符串并绑定它
  • 一般来说,你需要创建尽可能多的?,?,?,?,?,就像你有数组元素一样。
  • 我在询问之前进行了搜索,但没有找到我要查找的内容。如果之前没有被告知,我会感到惊讶。
  • 在这件事上,命名和匿名没有区别。该手册显然是错误的,在引用的句子中强调了命名的 placeholedr。

标签: php pdo prepared-statement


【解决方案1】:

这是我为模拟预期结果而编写的一些代码:

<?php
function preprepare(&$query, &$data) {
    preg_match_all('/\?/', $query, $matches, PREG_OFFSET_CAPTURE);
    $num = count($matches[0]);
    for ($i = $num; $i;) {
        --$i;
        if (array_key_exists($i, $data) && is_array($data[$i])) {
            $query = substr_replace($query, implode(',', array_fill(0, count($data[$i]), '?')), $matches[0][$i][1], strlen($matches[0][$i][0]));
            array_splice($data, $i, 1, $data[$i]);
        }
    }
}

$query = 'SELECT * FROM `table` WHERE `col1` = ? AND `col2` IN(?) AND `col3` = ? AND `col4` IN(?)';
$data = array('foo', array(1, 2, 3), 'bar', array(4, 2));
preprepare($query, $data);
var_dump($query, $data);
?>

它输出:

array (size=2)
  0 => string 'SELECT * FROM `table` WHERE `col1` = ? AND `col2` IN(?,?,?) AND `col3` = ? AND `col4` IN(?,?)' (length=93)
  1 => 
    array (size=7)
      0 => string 'foo' (length=3)
      1 => int 1
      2 => int 2
      3 => int 3
      4 => string 'bar' (length=3)
      5 => int 4
      6 => int 2

查询和数据随后可以用于普通的 PDO 准备语句。我不知道它是否解释了所有 PDO 魔法的好处,但到目前为止它运行良好。

【讨论】:

  • 虽然思路挺对,但是代码中充满了魔幻和无声的考虑。此外,您无论如何都不能使用 real prepare,这意味着每次值的数量发生变化时,您仍然需要 prepare() 一个新语句 - 所以,目标仍然没有达到。
  • 但是,您正朝着正确的方向前进。实现自己的占位符是唯一合适的解决方案。
  • 我认为我的解决方案比其他您必须自己按正确顺序构建阵列的解决方案要好一些。尽管查询需要“准备”两次,但它的工作方式与我期望的一样,如果它是本机支持的。
  • 试着再看远一点。 IN() 子句不是唯一需要处理的子句。 SET 子句是另一个要求自动化的子句。您真的要手动编写冗长的 INSERT 或 UPDATE 查询吗?将已经形成的数组发送到查询中不是更好吗?您将无法区分需要哪种格式。这是我就此事写的文章,涵盖了确切的问题。它还没有完成,但我希望你会觉得它很有趣:The Hitchhiker's Guide to SQL Injection protection
  • +1 供搭便车者参考!好文章,但是,我不是试图用准备好的语句来解决你提到的所有问题,只是多参数问题。我接受目前SET 是“太难”修复。据我所知,我的解决方案既不增加也不消除 PDO 任何格式检测问题。
猜你喜欢
  • 1970-01-01
  • 2010-11-30
  • 2010-11-05
  • 2012-08-05
  • 2013-10-26
  • 2016-09-10
  • 1970-01-01
相关资源
最近更新 更多