I have a script that I am updating by replacing the inline mysql queries with PDO prepared statements and queries. When the query is correct or returns a result, it works fine. However, when there is an error in the query statement try/catch dies not work. For example, I used this test code:
$query = $this->dbh->prepare('SELEC menu_item, hyperlink, admin FROM top_menu;');
try
{
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC));
die("success");
}
catch(Exception $e)
{
die("fail");
}
The query is wrong ("SELEC" instead of "SELECT"), so the flow of the script should go into the exception/error brackets, and yet it doesn't; I keep getting "success". I've tried catch(PDOException $e) instead of catch(Exception $e) with the exact same results.
What am I doing wrong, and how can I fix this? Thanks.
A similar problem has been answered here, PDO won't throw exceptions unless you tell it to. Have you run:
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
on the PDO object.
For PDO's fetch() on failure FALSE is returned. No exception is thrown.
See: http://php.net/manual/en/pdostatement.fetch.php
Related
after move all rowCount() Functions return fatal error
Fatal error: Call to a member function rowCount() on a non-object
i use this function like this :
$co = $pdo->query("SELECT * FROM `tbl_users`");
$pages->items_total = $co->rowCount();
This means something went wrong while executing the query. Perhaps something went wrong with the update and MySQL isn't running anymore? Verify this, make sure MySQL is running.
Also, you can try to run the same query in PhpMyAdmin to see if that works. If it does, you're sure this is a problem with PDO. If it doesn't, something must be wrong with the MySQL server.
But perhaps the easiest way to debug is to do something like this:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
With this, PDO will throw an exception when the query fails. Then put the query in a try ... catch block:
try {
$co = $pdo->query("SELECT * FROM `tbl_users`");
$pages->items_total = $co->rowCount();
} catch (PDOException $e) {
echo $e->getMessage();
}
This will give you more debug info. When the query fails, the exception will be caught by the catch block, and the message will be outputted. This message usually tells you where the problem is.
I have been working on a registration system for a while. The data interacting with db is pretty sensitive so I'm trying to pay extra attention to details.
This is an example of how I do inserts.
try{
$query="INSERT INTO account (user_id,password,salt) VALUES (:user_id,:password,:salt)";
$stmt=$db->prepare($query);
$params=array(':user_id'=>$userId,':password'=>$password,':salt'=>$salt);
$result=$stmt->execute($params);
if(!$result){
$db->rollBack();
doStaff();
}
}
catch(PDOException $e){
$db->rollBack();
doStaff();
}
I was wondering if there is any scenario that the result of an execute operation returns false but pdo does not throw exception? Should I check them both, or am I being paranoid?
The answer is yes.
A PDOException will be raised if you try to do something entirely impossible (i.e. connect to database with an incorrect hostname, authenticate with an incorrect username or password, etc.). However, if there is simply a syntax error or undefined reference in your SQL, PDOStatement::execute will silently return false. If you want to check for these errors and roll back the changes, you should certainly make sure that execute returns true.
However, instead of this, you can change this behavior so that SQL errors appear as exceptions:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Then, a single catch statement in your code will suffice.
After looking into using try catch blocks for my Pdo statements is it really a benefit? Does this just slow your code down?
I believe that there should be a try catch around the connection command in case the database connection fails. But does there really need to be try catch around each pre prepared statement? These should never change and never really error out.
Any thoughts?
I'm using Php and MySql.
There is no benefit to this:
try {
// exec statement
// exec statement
}
catch (Exception $e) {
// do nothing
}
If you aren't going to do anything with the error and provide a reasonable solution, then you may as well let the exception bubble up to the application's main "something went wrong" error page.
But you may want to do this:
// begin transaction
try {
// exec statement
// exec statement
// commit transaction
}
catch (Exception $e) {
// rollback transaction
// handle error or rethrow $e;
}
And prepared statements can throw exceptions. Perhaps a unique key is violated, or a foreign key constraint is, etc.
But the main point is, you don't use exceptions to hide or silence errors. You use them to catch an error, process it intelligently, and continue on accordingly.
Should I do
$dbh->beginTransaction();
try{
Or
try{
$dbh->beginTransaction();
It doesn't really matter, it will run the code indifferent of it's position.
But you want to put the rollback() in the catch, and with that setup it's not readable if you put begin outside.
I would vote for inside the try.
It probably doesn't really matter. However, it's better to place the beginTransaction outside the try. When the beginTransaction fails, it should not execute the rollback.
add it inside the try/catch block, so you can catch any PDOException:
try {
$dbh->beginTransaction(); // start transaction
$stmt = $dbh->query($query); // run your query
$dbh->commit(); // commit
} catch(PDOException $ex) { // if exception, catch it
$dbh->rollBack(); // rollback query
echo $ex->getMessage(); // echo exception message
}
In this case it doesn't matter, as beginTransaction will return false on failure. If it threw exceptions, you would want it inside of a nested try block (otherwise you'd execute rollBack() after catching the exception which would fail because no transaction was started).
If you want to catch the possible errors that the beginTranscation method should throw, go for the second one.
The doc for error handling for fetch() seems unclear and I haven't found an answer anywhere after a lot of searching. A common usage model for fetch as shown in the doc is:
while ( $row = $stmt->fetch() ) {
// do something with $row
}
The PHP doc at http://www.php.net/manual/en/pdostatement.fetch.php says:
In all cases, FALSE is returned on failure.
What does "failure" mean? An error? A failure to fetch more rows? My question is: when fetch() returns FALSE, what is best practice to detect errors? It seems like after the loop I need to distinguish between an error case and the "no more rows" case.
Should I call $stmt->errorCode() and see if it's '00000' ?
To handle query errors (sql errors not occurs on fetch) and more generaly PDO error you should try using PDO::ERRMODE_EXCEPTION.
Moreover the PdoStatement returned by query() implement Traversable , so you can skip the use of fetch() for simple query :
try {
$db = new PDO('sqlite:mydb.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set Errorhandling to Exception
foreach($db->query("SELECT...") as $row)
{
//Do domething
}
$db = null; // "Disconnect"
}
catch (PDOException $err) {
//Handling query/error
}
An execption will be thrown if query encounter an error (not fetch()).
Fetch will always return false when it reach the end of your result set.
fetch() will return false when there's no more data to be fetched. There could also be other case where there truly is a failure, e.g. mysql died or the connection was lost while doing the fetch loop. But generally speaking, that sort of "real" failure is fairly rare, and you'll most often get "false because there's no more data available".
If you're truly paranoid about writing error handling, then by all means, put an sql error code check after the while loop to catch the cases when something really did blow up.