so have no idea what's going on here
$link = new pdo('pgsql:dbname=' . $name . ';host=' . $host, $user, $password); $link->setattribute(pdo::attr_emulate_prepares, false); $link->setattribute(pdo::attr_errmode, pdo::errmode_exception); try { $stmt = $link->prepare("select s.*, d.invalid_column students s order s.student_id"); $stmt->execute(array(1)); } catch (pdoexception $e) { print $e->getmessage(); }
when run little code example, expect exception thrown (as d.invalid_column not real column , i'm passing in parameters cannot bound), thing happens execute returns false , nothing else. additionally $stmt->errorinfo()
blank , code 00000
makes hard add proper exception throw beyond super generic nothing else logs assist me in tracking errors down when end user reports error.
if add single '?' somewhere query, proper execution thrown (that d.invalid_column
not valid column), if add more parameters don't bind anything.
so ways query error:
1) rid parameters
2) add '?' query
is bug in pdo or what?
edit: setups throw exception (invalid column):
$stmt = $link->prepare("select s.*, d.invalid_column, ? students s order s.student_id"); $stmt->execute(array(1)); $stmt = $link->prepare("select s.*, d.invalid_column, ? students s order s.student_id"); $stmt->execute(array(1,2,3)); $stmt = $link->prepare("select s.*, d.invalid_column, ? students s order s.student_id"); $stmt->execute(); $stmt = $link->prepare("select s.*, d.invalid_column students s order s.student_id"); $stmt->execute();
it's when have no ?
in query , pass execute()
things fail silently , no explanation pdo.
that behavior reproducible current php (5.6.13), , query not sent server.
your case described in the doc as:
you cannot bind more values specified; if more keys exist in input_parameters in sql specified in pdo::prepare(), statement fail , error emitted.
0 value expected, 1 value given, , statement fails, false
being returned. far, works documented.
you may argue "an error emitted" imply when errmode_exception
on, exception thrown. that's argument, it's not obvious pdo developers agree it.
update:
why sqlcode
not set?
looking @ pdo source code, static php_method(pdostatement, execute)
handles pdo::execute(), can see errors handled macro: pdo_handle_stmt_err()
#define pdo_handle_stmt_err() if (strcmp(stmt->error_code, pdo_err_none)) { pdo_handle_error(stmt->dbh, stmt tsrmls_cc); }
the point that, when passing bound parameter when pdo expected none, query never makes sql engine, sql engine never has opportunity report error accompanied sqlstate
pdo not create fake sqlstate
on own, @ least no in case, sostmt->error_code
stays @ pdo_err_none
"00000"
.
it's understandable prefer exception raised, should suggest https://bugs.php.net
is same mysql ?
yes, root behavior same except mysql driver, prepare
sent sql engine if it's incorrect because of bad column, fails earlier , real sql error. on other hand, pgsql driver has different implementation makes defer server-side prepare
. particular behavior discussed in detail @ php postgres pdo driver not support prepared statement?
anyway, here's case mysql demonstrates explanation, is:
- the query expects 0 parameter, 1 given
$stmt->execute
returns false- no exception gets raised
- pdo::errorcode
00000
code:
$link = new pdo('mysql:dbname=' . $name . ';host=' . $host, $user, $password); $link->setattribute(pdo::attr_emulate_prepares, false); $link->setattribute(pdo::attr_errmode, pdo::errmode_exception); try { $stmt = $link->prepare("select 1"); $rc=$stmt->execute(array(1)); if ($rc===false) echo "query failed, errorcode=", $link->errorcode(), "\n"; else echo "query succeeded, errorcode=", $link->errorcode(), "\n"; } catch (pdoexception $e) { print "a pdoexception has occurred"; print $e->getmessage(); }
result:
query failed, errorcode=00000
what happens under hood prepare
sent server , succeeds, execute
step cancelled pdo due mismatch in parameters.
here's case differs in fact query refers non-existing column. i'm adding print show $stmt->execute
not called, exception raised $stmt->prepare
code:
$link = new pdo('mysql:dbname=' . $name . ';host=' . $host, $user, $password); $link->setattribute(pdo::attr_emulate_prepares, false); $link->setattribute(pdo::attr_errmode, pdo::errmode_exception); try { $stmt = $link->prepare("select nonexisting"); echo "executing query\n"; $rc=$stmt->execute(array(1)); if ($rc===false) echo "query failed, errorcode=", $link->errorcode(), "\n"; else echo "query succeeded, errorcode=", $link->errorcode(), "\n"; } catch (pdoexception $e) { print "a pdoexception has occurred"; print $e->getmessage(); }
result:
a pdoexception has occurredsqlstate[42s22]: column not found: 1054 unknown column 'nonexisting' in 'field list'
note how "executing query" step never happens, because it's prepare
fails, server-side.
conclusion
when query sent server, in prepare() or execute(), , it's server generates error, can expect pdoexception raised.
when query not sent server execution step, pdo execute() can fail (returns false) no exception thrown ,
errorcode()
stays @00000
Comments
Post a Comment