在我们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;
}
}