如果声明对象未设置,是否需要调用PDOStatement :: closeCursor()?

[英]Is a call to PDOStatement::closeCursor() necessary if the statement object is unset anway?

I'm utilizing a Mysql based PDO connection with PDOStatement (::prepare(); ::execute()) and I've run over some code from a previous developer that utilizes PDOStatement::closeCursor() in a method.

我正在使用与PDOStatement(:: prepare(); :: execute())的基于Mysql的PDO连接,并且我在一个方法中运行了一些利用PDOStatement :: closeCursor()的开发人员的代码。

The statement is unset at the end of the function anyway:


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));

    $cart = $stmt->fetch();


    return $result;

In my mental model, I'd say that the PDOStatement is cleared here anyway, as I exepect the object to take care of this housekeeping (encapsulation basics). Therefore calling PDOStatement::closeCursor() looks supferfluous to me, especially, as this might not be exactly what is wanted here: As the statement is not to be re-used, I don't need to close the cursor at all.

在我的心智模型中,我会说PDOStatement无论如何都在这里被清除,因为我发现这个对象要处理这个内务处理(封装基础知识)。因此,调用PDOStatement :: closeCursor()看起来对我来说是多余的,特别是因为这可能不是这里想要的:因为语句不能被重用,所以我根本不需要关闭游标。

side-note: this code is exemplary, in the real code, there is even an exception thrown after $stmt->execute(...) if the row-count is not one (1).

注意:此代码是示例性的,在实际代码中,如果行计数不是一(1),则在$ stmt-> execute(...)之后甚至会抛出异常。

Existing Material on Stackoverflow

Charles commmented back in May 2011 in the question pdo free result:


Not just some drivers -- some settings provided by drivers require closing the result set before firing off another query, like turning off MySQL's PDO::MYSQL_ATTR_USE_BUFFERED_QUERY. Thankfully you can call closeCursor and it will successfully do nothing when it doesn't need to take action. Otherwise simply unsetting the variable containing the statement handle will clean up.

不只是一些驱动程序 - 驱动程序提供的某些设置需要在触发另一个查询之前关闭结果集,例如关闭MySQL的PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY。值得庆幸的是,你可以调用closeCursor,当它不需要采取行动时它将成功地做任何事情。否则,只需取消设置包含语句句柄的变量即可清除。

Another question When should I use closeCursor() for PDO statements? has no accepted answer which I don't wonder about because it's all wishy-washy.


In Reusing PDO statement var crashes the process there is a comment made that unsetting a variable does not get all errors (memory corruption bugs) out of the way:


[...] I did try to unset the statement var before reassigning it but it didn't help. [...]

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

However I don't know if this is also true for local variables whose scope is to be gone. I also don't use mod_php as SAPI.


Related Bug Material

2 个解决方案



pdo_mysql_stmt_dtor() runs the same cleanup operations as pdo_mysql_stmt_cursor_closer(), so as long as the statement object is either explicitly unset or goes out of scope, the operations will always be performed.


It is therefore not strictly necessary to call closeCursor() if the statement is about to be destroyed anyway. Personally I would do it anyway as I like to be explicit for readability, but that comes down to personal stylistic preferences.


Based on the references above, this can only be said for certain about PDO_mysql - for other drivers this may not hold true.

基于上面的引用,这只能说明某些关于PDO_mysql - 对于其他驱动程序,这可能不适用。



My understanding of PDOStatement::closeCursor() is that it clears the result of a executed query. But not affects a PDOStatement at all (just the result of its execution).

我对PDOStatement :: closeCursor()的理解是它清除了执行查询的结果。但是根本不会影响PDOStatement(只是执行的结果)。

From the PHP Documnetation about this method:

从PHP Documnetation有关此方法:

frees up the connection to the server so that other SQL statements may be issued



This method is useful for database drivers that do not support executing a PDOStatement object when a previously executed PDOStatement object still has unfetched rows.


let me assume that you should make after every execution and fetch of all data you need form the current query execution a call to the PDOStatement::closeCursor() method. I think the MySQL driver for PDO does this automatically but there seems to be problems with some drivers which does not automatically free up the result.

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

So if you switch to another DB driver which does not free up the pending result of the query you run into an error.




© 2014-2019 ITdaan.com 粤ICP备14056181号