ID: 45120
Updated by: [EMAIL PROTECTED]
Reported By: morrisdavidd at gmail dot com
Status: Open
Bug Type: PDO related
Operating System: Linux
PHP Version: 5.2.6
New Comment:
On the first look this seems to be a PDO not a PDO_MYSQL (or any other
driver) bug.
>From pdo_stmt.c, static PHP_METHOD(PDOStatement, execute), around line
450:
if (PDO_PLACEHOLDER_NONE == stmt->supports_placeholders) {
/* handle the emulated parameter binding,
* stmt->active_query_string holds the query with binds
expanded and
* quoted.
*/
ret = pdo_parse_params(stmt, stmt->query_string,
stmt->query_stringlen,
&stmt->active_query_string,
&stmt->active_query_stringlen
TSRMLS_CC);
[...]
}
For some drivers, PDO assigns the return value of its
pdo_parse_params() function to ret. And then the code flow continues and
eventually the driver gets called to execute the statement (depending on
the driver features):
if (stmt->methods->executer(stmt TSRMLS_CC)) {
if (stmt->active_query_string && stmt->active_query_string !=
stmt->query_string) {
efree(stmt->active_query_string);
}
stmt->active_query_string = NULL;
if (!stmt->executed) {
/* this is the first execute */
if (stmt->dbh->alloc_own_columns && !stmt->columns) {
/* for "big boy" drivers, we need to allocate
memory to fetch
* the results into, so lets do that now */
ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
}
stmt->executed = 1;
}
if (ret && !dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_POST
TSRMLS_CC)) {
RETURN_FALSE;
}
RETURN_BOOL(ret);
}
ret (returned ny pdo_parse_params()) will be overwritten only on the
first execution. Upon subsequent executions the driver cannot set ret.
You get a bool(false) because pdo_parse_params() has returned 0 (=
success) and the return value of PDO_MYSQL has been ignored.
Maybe it should read like this:
if (ret = stmt->methods->executer(stmt TSRMLS_CC)) {
Previous Comments:
------------------------------------------------------------------------
[2008-05-28 20:53:59] morrisdavidd at gmail dot com
Description:
------------
The query is the exact same every time the statement is called. There
are no parameters being bound. However, the function only returns true
the first time the PDO->execute() is called.
As per:
http://us3.php.net/manual/en/pdostatement.execute.php
"Return Values
Returns TRUE on success or FALSE on failure."
I've run a test where I had it sleep after the first $stmt->execute()
long enough for me to change the value of the data being selected from
the database (And I output the data being selected to make sure it was
retrieved in its changed form the second time around). It still returned
FALSE.
However, the documentation for the function states: "Execute the
prepared statement." ... "Returns TRUE on success or FALSE on failure."
So, the function returns FALSE when it executed the prepared statement
successfully.
Reproduce code:
---------------
Obviously You'll have to change the database name, user, pass,
table...
<?php
$table = "SystemInformation";
$pdoDb = new PDO("mysql:host=localhost;dbname=eta_manybodystate",
DB_USER, DB_PWD);
$stmt = $pdoDb->prepare("SELECT * FROM `".$table."` LIMIT 1;");
$foo = $stmt->execute();
$stmt->closeCursor();
echo "foo: ";
var_dump($foo);
$bar = $stmt->execute();
$stmt->closeCursor();
echo "bar: ";
var_dump($bar);
$foo2 = $stmt->execute();
$stmt->closeCursor();
echo "foo2: ";
var_dump($foo2);
$bar2 = $stmt->execute();
$stmt->closeCursor();
echo "bar2: ";
var_dump($bar2);
?>
Expected result:
----------------
foo: bool(true)
bar: bool(true)
foo2: bool(true)
bar2: bool(true)
Actual result:
--------------
foo: bool(true)
bar: bool(false)
foo2: bool(false)
bar2: bool(false)
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=45120&edit=1