Reputation:
I am pretty much familiar with MySQLi and was trying PDO, I heard it is better. I was going through the tutorial present here. They say that PDO throws an exception when PDO::ERRMODE_EXCEPTION is set and we accidentally do something wrong with the query (for example, typing it incorrectly, DELECT instead of SELECT). I typed in the same wrong query to see the error and exception message on my local environment. I have latest WAMP installed with PHP 5.5, MySQL 5.6 and Apache 2.4.9 in my 32-bit Windows 7 PC, but did not get what I was expecting, no exception was thrown there. I tried the same code posted in the tutorial:
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
# UH-OH! Typed DELECT instead of SELECT!
$DBH->prepare('DELECT name FROM people');
}
catch(PDOException $e) {
echo "I'm sorry, Dave. I'm afraid I can't do that.";
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
No PDOError.txt, no error message. Is something wrong with the tutorial or my environment? Or there are cases where PDO fails to throw exceptions? I have PDO driver installed for MySQL.
Upvotes: 6
Views: 3830
Reputation: 94662
This is actually to do with another attribute of the PDO connection that you may not have considered yet. And that is PDO::ATTR_EMULATE_PREPARES
If you add this attribute, and set it to false
it will tell the PDO extension to issue the prepare
to the database for compilation, optimization and execution planning, at the point you issue the ->prepare()
. If you leave it unset it takes the default of true
, which tells the extension to EMULATE the compilation. In other words, it will wait until you issue the ->execute()
before the statement gets compiled and errors are reported.
PDO::ATTR_EMULATE_PREPARES Enables or disables emulation of prepared statements. Some drivers do not support native prepared statements or have limited support for them. Use this setting to force PDO to either always emulate prepared statements (if TRUE), or to try to use native prepared statements (if FALSE). It will always fall back to emulating the prepared statement if the driver cannot successfully prepare the current query.
So run your code with this extra Attribute setting, and see the difference.
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$DBH->setAttribute( PDO::ATTR_EMULATE_PREPARES, FALSE );
# UH-OH! Typed DELECT instead of SELECT!
$DBH->prepare('DELECT name FROM people');
}
catch(PDOException $e) {
echo "I'm sorry, Dave. I'm afraid I can't do that.";
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
Now you will get the message and the file will be created containing the error message
Upvotes: 4
Reputation: 74217
It's probably failing because the query never gets executed and is awaiting further instructions.
Since it figures that nothing fires, then it's all valid in the eye of PDO; that is my analogy on this.
Execute it and you will see it will throw an exception.
Either by executing it after the prepare, or a simple ->query()
rather than ->prepare()
.
Upvotes: 3