【问题标题】:Is a call to PDOStatement::closeCursor() necessary if the statement object is unset anway?如果语句对象未设置,是否需要调用 PDOStatement::closeCursor() ?
【发布时间】:2014-08-25 14:03:26
【问题描述】:

我正在使用带有 PDOStatement (::prepare(); ::execute()) 的基于 Mysql 的 PDO 连接,并且我运行过之前开发人员的一些代码在方法中使用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(...) 之后引发异常。

Stackoverflow 上的现有资料

Charlescommmented back in May 2011在问题pdo free result:

只是一些驱动程序——驱动程序提供的一些设置需要在触发另一个查询之前关闭结果集,比如关闭MySQL的PDO::MYSQL_ATTR_USE_BUFFERED_QUERY。谢天谢地,您可以致电closeCursor,当它不需要采取行动时,它将成功地什么都不做。否则,只需取消设置包含语句句柄的变量即可清理。

另一个问题When should I use closeCursor() for PDO statements? 没有可接受的答案,我并不怀疑,因为这都是空想。

Reusing PDO statement var crashes the process 中有 a comment made 表示取消设置变量并不能消除所有错误(内存损坏错误):

[...] 我确实尝试在重新分配语句 var 之前取消设置它,但它没有帮助。 [...]

但是我不知道这是否也适用于范围将消失的局部变量。我也不使用mod_php 作为 SAPI。

相关错误材料

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    pdo_mysql_stmt_dtor() 运行与pdo_mysql_stmt_cursor_closer() 相同的清理操作,因此只要语句对象明确取消设置或超出范围,将始终执行操作。

    因此,如果语句即将被销毁,则不必调用closeCursor()。就我个人而言,无论如何我都会这样做,因为我喜欢明确地提高可读性,但这归结为个人风格偏好。

    根据上面的参考资料,这只能肯定地说是关于 PDO_mysql - 对于其他驱动程序,这可能不成立。

    【讨论】:

    【解决方案2】:

    我对@9​​87654322@ 的理解是它清除了执行查询的结果。但完全不影响PDOStatement(只是其执行的结果)。

    From the PHP Documnetation about this method:

    释放与服务器的连接,以便其他 SQL 语句可以 发布

    此方法对于不支持的数据库驱动程序很有用 当先前执行的 PDOStatement 对象仍有未提取的行时执行 PDOStatement 对象。

    让我假设您应该在每次执行并从当前查询执行中获取所需的所有数据之后调用PDOStatement::closeCursor() 方法。我认为 PDO 的 MySQL 驱动程序会自动执行此操作,但某些驱动程序似乎存在问题,无法自动释放结果。

    因此,如果您切换到另一个数据库驱动程序,它不会释放查询的待处理结果,您会遇到错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 2012-10-02
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多