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.
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));
$stmt->setFetchMode(PDO::FETCH_OBJ);
$cart = $stmt->fetch();
$stmt->closeCursor();
...
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.
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).
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 callcloseCursor
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.
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. [...]
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.
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.
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).
From the PHP Documnetation about this method:
frees up the connection to the server so that other SQL statements may be issued
and
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.
So if you switch to another DB driver which does not free up the pending result of the query you run into an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With