user5818995
user5818995

Reputation:

PDO not throwing exception on wrong SQL query

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

Answers (2)

RiggsFolly
RiggsFolly

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

Funk Forty Niner
Funk Forty Niner

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

Related Questions