【问题标题】:PDO bindColumn and PDO::FETCH_BOUND -- compulsory or optional?PDO bindColumn 和 PDO::FETCH_BOUND -- 强制还是可选?
【发布时间】:2015-12-23 15:06:52
【问题描述】:

在我们的 PHP 代码中的许多地方,(如果重要的话,使用 postgres) 我们有类似的东西:

$q  = "SELECT DISTINCT a.id FROM alarms.current a, entities e, installations i ";
$q .= "WHERE i.\"entityId\"=e.id AND a.installationid=i.id AND ";
$q .= "e.id=".$entityId;

$stmt = $db->query($q);
$stmt->bindColumn("id", $alarmId);

if ($stmt->fetch(PDO::FETCH_ASSOC))
....etc

现在根据我对文档的阅读,如果您希望从绑定列更新变量,您应该使用 PDO::FETCH_BOUND。但我们没有,据我所知,没有人抱怨过性能。

谁能解释一下为什么这个明显错误的代码实际上可以正常工作?

【问题讨论】:

    标签: php postgresql pdo


    【解决方案1】:

    虽然bindColumn 的 PHP 文档中的示例使用了PDO::FETCH_BOUND,这确实表明这种获取方式是使用bindColumn 所必需的,但它没有明确说明这是一项要求。它只是说

    PDOStatement::bindColumn() 安排将特定变量绑定到查询结果集中的给定列。每次调用 PDOStatement::fetch() 或 PDOStatement::fetchAll() 都会更新所有绑定到列的变量。

    经过一些测试,我确定无论使用哪种获取样式,都会发生这种情况。我认为代码中的fetch 调用实际上并未被提取到变量中,这实际上意味着创建了一个关联数组并没有分配任何内容,而提取的副作用填充了$alarmId 变量。

    【讨论】:

    • 谢谢 - 这是我从我们的两个大型应用程序似乎“错误地”执行此操作但它们有效这一事实中得出的唯一结论。我更希望将它们更改为“正确”地执行此操作,以防它仅适用于一种数据库类型,但我现在将限制自己使用@FIXMEs 粘贴代码。
    • 由于PDO::FETCH_ASSOC 实际上并没有被提取到任何东西中,我无法想象为什么将其更改为PDO::FETCH_BOUND(在我看来确实不那么令人困惑)会导致任何问题。当我用所有不同的 fetch 样式测试它时,我实际上是在使用 MySQL,它的价值。
    • 不要惊慌——我刚刚意识到有一种情况,如文档所暗示的那样,更改为 FETCH_BOUND 会破坏我的代码。
    • @davidcollier 这很有趣。这种情况是否仍然像您的问题一样使用if ($stmt->fetch(PDO::FETCH_ASSOC)),还是实际上是在分配,例如if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
    • 显然我错过了解决这个问题的机会 - 它应该是:不要恐慌 - 我刚刚意识到有一种情况,如文档所暗示的那样,更改为 FETCH_BOUND 会破坏我的代码.程序员已经设置了一堆 bindParams,但随后使用 FETCH_ASSOC 样式的返回值来决定是否有数据要处理。修复它以使用 FETCH_BOUND 会强制返回值为 TRUE,这将导致无限循环。
    【解决方案2】:

    继续@DontPanic 的 cmets,以下是我更喜欢使用绑定参数的方式:

    /**
    * @param $id
    *
    * @return array|false
    */
    public function retrieveImage($id)
    {
        $conn = $this->dbh->getInstance('LocalMSSQL');
        $stmt = $conn->prepare("SELECT inputType, blob FROM images WHERE id = ?");
    
        $stmt->bindValue(1, $id, PDO::PARAM_INT);
        $stmt->execute();
    
        $resultSet = [
            'inputType' => null,
            'blob' => null,
        ];
    
        $stmt->bindColumn(1, $resultSet['inputType'], PDO::PARAM_STR);
        $stmt->bindColumn(2, $resultSet['blob'], PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
    
        if ($stmt->fetch()) {
            return $resultSet;
        } else {
            return false;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 2011-06-26
      • 2017-11-10
      • 2013-04-18
      • 2011-04-13
      • 2015-02-18
      • 2015-03-13
      • 2011-08-02
      相关资源
      最近更新 更多