PDO->bindParam, PDO->bindValue and PDO->closeCursor

坚强是说给别人听的谎言 提交于 2019-12-10 11:45:28

问题


So far I have been using PDO->bindParam however while reading the manual I found PDO->bindValue from what I can tell PDO->bindValue passes by value where as PDO->bindParam passes by reference, is this the only difference?

$modThread = db()->prepare("UPDATE `threads` SET `modtime` = UNIX_TIMESTAMP( ) WHERE `threadid` =:id LIMIT 1");

while(something)
{
        $modThread->bindParam(':id', $thread);
        $modThread->execute();
//*******************HERE********************//
}

Again while reading the manual I found: PDO->closeCursor should I place it where marked? Is it optional/automatically called? Seems only certain drivers need it. Will calling it on a driver that doesn't need/support it cause errors? How about MySQL?


回答1:


The 'recurring' bindParam() here is not really necessary:

$thread = 0;
$modThread->bindParam(':id', $thread);

while($thread < 20)
{
    $thread++;
    $modThread->execute(); //executing with the new value, which you couldn't do with bindValue
}

You don't need a closeCursor() when there is no resultset (i.e, only with SELECT s or procedures giving results back) , but usually I've already done a fetchAll somewhere in a previous statement / row.




回答2:


This isn't true. If you find yourself needing to use closeCursor, one of the most optimal times is for insert/update/delete commands, and rarely for SELECT statements for which you have already fetched results.

For example, if you select all records from a table, then issue $stmt->fetch(), this actually accomplishes the goal for closeCursor immediately as the rows are now no longer in an unfetched status.

From the manual:

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. If your database driver suffers from this limitation, the problem may manifest itself in an out-of-sequence error.

When you will really need closeCursor is during any of the following instances:

  • If your DB driver doesn't allow for a new stmt to be executed while unfetched rows are available from the previous execute
  • You have multiple prepared statements and would like to execute them one-after-another ($stmt1->execute(); $stmt->closeCursor(); $stmt2->execute(); $stmt2->closeCursor(); $stmt3...etc)
  • You have multiple stmts that must execute insert/update/delete inside the same block. This is true because, while you dont get mysql row results back, you DO get number of affected rows result set back (which is still a result).
  • When using transactions
  • When you want to issue select-style prepared statements and execute them, but not retrieve the data until later

When you don't need the closeCursor statement:

  • If you have already fetched the rows (as with $stmt->fetch()) before your next statement is to be executed. At this point the rows are in a "fetched" state and frees up the driver to execute new statements.

Just as useful for closing a cursor is unset() (ie: unset($stmt)) and setting the statement to null ($stmt = null), opening the doors for the built-in Garbage Collector to clear everything up.

See the manual for more information: http://php.net/manual/en/pdostatement.closecursor.php



来源:https://stackoverflow.com/questions/3725346/pdo-bindparam-pdo-bindvalue-and-pdo-closecursor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!