我正在使用基于Mysql的 PDO连接与 PDOStatement (::prepare()
; ::execute()
)并且我已经运行来自之前在方法中使用PDOStatement::closeCursor()
的开发人员的一些代码。
无论如何,语句在函数结束时未设置:
public function fooBar($identifier)
{
...
/** @var $dbc PDO */
$dbc = $conn->getConnection();
$stmt = $dbc->prepare('SELECT orderType, orderComment, payload FROM cart WHERE identifier = :identifier');
$stmt->execute(array('identifier' => $identifier));
$stmt->setFetchMode(PDO::FETCH_OBJ);
$cart = $stmt->fetch();
$stmt->closeCursor();
...
return $result;
}
在我的心理模型中,我说无论如何都要在这里清除PDOStatement,因为我要求对象来处理这种内务管理(封装基础知识)。因此,调用PDOStatement::closeCursor()
看起来对我来说是多余的,特别是因为这可能不是这里想要的:因为语句不能重复使用,所以我根本不需要关闭光标。
旁注:此代码是示例性的,在实际代码中,如果行计数不是一(1),甚至会在
$stmt->execute(...)
之后抛出异常。
commmented back in May 2011 pdo free result:
不是只是一些驱动程序 - 驱动程序提供的一些设置需要在触发另一个查询之前关闭结果集,例如关闭MySQL {{1 }}。值得庆幸的是,你可以致电
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
,当它不需要采取行动时,它将成功地做任何事情。否则,只需取消设置包含语句句柄的变量即可清除。
另一个问题When should I use closeCursor() for PDO statements?没有被接受的答案,我不会对此感到疑惑,因为它完全没什么问题。
在 Reusing PDO statement var crashes the process 中,a comment made取消设置变量并不会导致所有错误(内存损坏错误)无法解决:
[...]我确实尝试在重新分配之前取消设置语句var,但它没有帮助。 [...]
但是我不知道对于范围不大的局部变量是否也是如此。我也没有使用closeCursor
作为SAPI。
答案 0 :(得分:8)
pdo_mysql_stmt_dtor()
运行与pdo_mysql_stmt_cursor_closer()
相同的清理操作,因此只要语句对象显式未设置或超出范围,操作将始终执行。
因此,如果声明即将被销毁,则不必严格调用closeCursor()
。就个人而言,我会这样做,因为我喜欢明确可读性,但这归结为个人风格偏好。
根据上面的参考资料,这可以仅对于某些关于PDO_mysql的说法 - 对于其他驱动程序,这可能不成立。
答案 1 :(得分:1)
我对PDOStatement::closeCursor()
的理解是它清除了执行查询的结果。但是根本不会影响PDOStatement
(只是执行的结果)。
From the PHP Documnetation about this method:
释放与服务器的连接,以便其他SQL语句可以 发出
和
此方法对不支持的数据库驱动程序很有用 当先前执行的PDOStatement对象仍具有未取消的行时,执行PDOStatement对象。
让我假设您应该在每次执行后获取并从当前查询执行中获取所需的所有数据,并调用PDOStatement::closeCursor()
方法。我认为PDO的MySQL驱动程序会自动执行此操作,但某些驱动程序似乎存在问题,这些驱动程序不会自动释放结果。
因此,如果您切换到另一个没有释放查询的待处理结果的数据库驱动程序,则会遇到错误。