问题
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