【问题标题】:PDO Prepare Not Replacing Named PlaceholdersPDO 准备不替换命名占位符
【发布时间】:2014-05-03 17:58:07
【问题描述】:

我尝试使用命名占位符来填写数据,如下所示:

    $STH = $DBH->prepare("SELECT mixes.* FROM mixes JOIN(SELECT id FROM mixes WHERE id NOT IN ( :noredo_ids )  ORDER BY RAND() LIMIT 1) ips on mixes.id = ips.id"); 
    $STH->bindParam(':noredo_ids', $_GET["noredo"]);
    $STH->setFetchMode(PDO::FETCH_ASSOC); 
    $STH->execute();

也尝试过

    $arr2["ids"] = $_GET["noredo"];

    $STH = $DBH->prepare("SELECT mixes.* FROM mixes JOIN(SELECT id FROM mixes WHERE id NOT IN ( :ids )  ORDER BY RAND() LIMIT 1) ips on mixes.id = ips.id"); 
    $STH->setFetchMode(PDO::FETCH_ASSOC); 
    $STH->execute($arr2);

但这些都不起作用。但是当我尝试手动输入字符串而不是使用占位符时,它确实有效:

        $arr2["ids"] = $_GET["noredo"];

    $STH = $DBH->prepare("SELECT mixes.* FROM mixes JOIN(SELECT id FROM mixes WHERE id NOT IN (". $arr2['ids'] .")  ORDER BY RAND() LIMIT 1) ips on mixes.id = ips.id"); 
    $STH->setFetchMode(PDO::FETCH_ASSOC); 
    $STH->execute();

我应该手动转义字符串吗?我错过了一些明显的东西吗?谢谢!

【问题讨论】:

标签: php mysql pdo


【解决方案1】:

我不确定,因为 PHP 关于准备好的语句的命名占位符的文档对此有点模糊。 http://php.net/manual/en/pdostatement.bindparam.php

但如果 $_GET['noredo'] 是一个 ID 数组,您需要先 implode(',',$_GET['noredo']) 在传递到准备好的语句之前,我不相信占位符替换足够聪明,可以将数组展平成一个逗号分隔的列表,可以在 IN() 中使用。

在 PHP 文档中,替换是单个值,而不是值数组,所以(这是我模糊的地方)我不相信它会在您传递的数组中查找 :named_placeholder。

但话又说回来,我只使用了 ?准备好的语句的占位符...

【讨论】:

    【解决方案2】:

    查询参数始终代替 SQL 表达式中的单个标量值。

    因此,如果您希望 $_GET["noredo"] 是一个数组或逗号分隔的值列表,那么您所做的将不起作用。查询将像您执行此操作一样运行:

    WHERE id NOT IN ( '1,2,3,4' )
    

    包含逗号分隔列表的带引号的字符串值与一系列逗号分隔值不同。它是一个字符串,在数字上下文中,SQL 会将 '1,2,3,4' 转换为标量数字 1。

    因此,如果要在 IN() 谓词中绑定多个值,则需要使用多个占位符。

    $id_array = (array) $_GET["noredo"];
    
    $placeholders = implode(",", array_fill(0,count($id_array),"?"));
    
    $STH = $DBH->prepare("SELECT mixes.* FROM mixes JOIN(SELECT id FROM mixes 
        WHERE id NOT IN ( $placeholders )  ORDER BY RAND() LIMIT 1) ips on mixes.id = ips.id"); 
    
    $STH->execute($id_array);
    

    【讨论】:

      【解决方案3】:

      第二个示例不起作用,因为据我所知,您使用的是$arr2["ids"] 而不是$arr2[":ids"]。也就是说,您仍然必须使用完整的参数名称。

      此外,您应该确保您尝试插入的值已正确清理并且不会导致语法错误。

      【讨论】:

      • 我尝试将其更改为 $arr2[":ids"],但仍然无法正常工作。
      猜你喜欢
      • 2016-12-23
      • 2012-12-14
      • 2014-05-23
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多