Php PDO bindColumn和PDO::FETCH_-BOUND——强制还是可选?

Php PDO bindColumn和PDO::FETCH_-BOUND——强制还是可选?,php,postgresql,pdo,Php,Postgresql,Pdo,在我们的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); $

在我们的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文档中的
bindColumn
的示例使用了
PDO::FETCH_-BOUND
,这确实表明为了使用
bindColumn
,这种提取样式是必要的,它没有明确说明这是一项要求。它只说

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


经过一些测试后,我确定无论使用何种获取样式,都会发生这种情况。我认为,代码中的
fetch
调用实际上并没有被提取到变量中,这一事实实际上只是意味着创建了一个关联数组,并且没有赋值,虽然fetch的副作用填充了
$alarmId
变量。

虽然PHP文档中的
bindColumn
示例使用了
PDO::fetch_-BOUND
,但这确实表明使用
bindColumn
需要此fetch样式,但它没有明确说明这是一项要求。它只说

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


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

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

/**
* @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;
    }
}

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

/**
* @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;
    }
}

谢谢-这是我能从以下事实中得出的唯一结论:我们的两个大型应用程序似乎做得“不对”,但它们仍然有效。我更希望将它们更改为“正确”,以防只对一种数据库类型使用这种方式,但我现在将限制自己使用@FIXMEs来涂抹代码。由于
PDO::FETCH_ASSOC
实际上没有被提取到任何内容中,我无法想象为什么要将其更改为
PDO::FETCH_BOUND
(在我看来,这看起来不那么令人困惑)可能会导致任何问题。当我测试MySQL时,我实际上使用了所有不同的获取样式,这是值得的。不要惊慌-我刚刚意识到有一种情况,更改为fetch_-BOUND,正如文档所暗示的,会破坏我的代码。@davidcollier这很有趣。这种情况是否仍然使用
if($stmt->fetch(PDO::fetch_ASSOC))
与您的问题类似,或者它实际上是赋值的,比如
如果($row=$stmt->fetch(PDO::fetch_ASSOC))
?显然,我错过了修复这个问题的机会——应该是这样写的:不要惊慌——我刚刚意识到,如果更改为FETCH\u-BOUND,正如文档所暗示的那样,将会破坏我的代码。程序员设置了一组bindParams,但随后使用FETCH\u-ASSOC样式的返回值来决定有数据需要处理。将其修复为使用FETCH_BOUND将强制返回值为TRUE,这将导致一个无限循环。感谢-这是我从我们的两个大型应用程序似乎做得“错误”,但它们仍然工作的事实中得出的唯一结论。我更希望它们被更改为“正确”,以防只对一种数据库类型使用这种方式,但我现在将限制自己使用@FIXMEs来涂抹代码。由于
PDO::FETCH_ASSOC
实际上没有被提取到任何内容中,我无法想象为什么要将其更改为
PDO::FETCH_BOUND
(在我看来,这看起来不那么混乱)可能会导致任何问题。当我测试MySQL时,我实际上使用了所有不同的获取样式,这是值得的。不要惊慌-我刚刚意识到有一种情况,更改为fetch_-BOUND,正如文档所暗示的,会破坏我的代码。@davidcollier这很有趣。这种情况是否仍然使用
if($stmt->fetch(PDO::fetch_ASSOC))
与您的问题类似,或者它实际上是赋值的,比如
如果($row=$stmt->fetch(PDO::fetch_ASSOC))
?显然,我错过了修复这个问题的机会——应该是这样写的:不要惊慌——我刚刚意识到,如果更改为FETCH\u-BOUND,正如文档所暗示的那样,将会破坏我的代码。程序员设置了一组bindParams,但随后使用FETCH\u-ASSOC样式的返回值来决定有数据要处理。将其修复为使用FETCH_-BOUND将强制返回值为TRUE,这将导致无限循环。