PDO bindColumn和PDO::FETCH_BOUND——强制或可选


PDO bindColumn and PDO::FETCH_BOUND -- compulsory or optional?

在我们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调用实际上并没有被提取到变量中,这实际上只是意味着创建了一个关联数组,并且不给任何对象赋值,而提取的副作用填充了$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;
    }
}