Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

php

mysql

pdo

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

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.

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.

Related Bug Material

  • Bug #66878 Multiple rowsets not returned unless PDO statement object is unset()
like image 924
hakre Avatar asked Jul 04 '14 09:07

hakre


2 Answers

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.

like image 100
DaveRandom Avatar answered Nov 07 '22 01:11

DaveRandom


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.

like image 29
TiMESPLiNTER Avatar answered Nov 07 '22 02:11

TiMESPLiNTER