-->

MySQLi Error Handling?

2020-08-01 06:08发布

问题:

I started using OO-MySQLi after procedural MySQL and I have a problem.

In production environment my system displays all errors as a custom page. MySQLi errors is an "error" too and I want catch them, but in documentation described only one way to do this:

if (!$mysqli->query("SET a=1")) {
    exit('An error occurred: ' . $mysqli->error);
}

(just for example). This is a very bad way, because in my system I'm doing many things when error occurred, like logging, calling events, etc.

Of course, I can extend mysqli class, for example:

class myMysqli {
    public function __construct(/* ... */)
    {
        parent::__construct(/* ... */);
    }

    public function query(/* .. */)
    {
        parent::query(/* ... */);

        if($this->errno !== 0)
        {
            // An error occurred
        }
    }
}
$mysqli = new myMysqli(/* ... */);
$mysqli->query(/* ... */);

But this way I need to extend almost ALL methods where error can occur. Moreover, MySQLi provides prepared statements (mysqli_stmt class) that has its own errors!

Can you know a better way to handle MySQLi errors? Thank you in advance.


Added

About exceptions: Do I understand correctly that with exceptions I need do something like this:

try {
    $mysqli->query(/* ... */);
} catch (Exception $e) {
    // An error occurred
}

But this is similar to

if(!$mysqli->query(/* ... */))
{
    // An error occured
} 

What a difference?

回答1:

I use the try...catch method like this...

try {
    // get result of record from 'id'
    $query = "SELECT * FROM models WHERE id =$id";
    $result = $mysqli->query($query);

    if (!$result) {
        throw new Exception($mysqli->error());      
    } 
    $row = $result->fetch_array(); 
 }
 catch (Exception $e)  
 {
     echo "We are currently experiencing issues. Please try again later.";
     echo $e->getMessage();
 } 
 finally
 {
      $result->free();
 }

Does that help at all?

You use 'try' to test a condition and throw an exception if it returns true (!$result). And use 'catch' to catch everything else that might just happen!



回答2:

First of all, your old approach was wrong.

exit('An error occurred: ' . $mysqli->error);

is a bad practice in general and shouldn't be used with mysqli as well.

What you really want is error/exception handler. Where you can do whatever things like logging, calling events, showing pages.

Exception is better than regular error - so, set your mysqli in exception mode as shown in other answer, and then catch all the errors in error handler. While try..catch have to be used only when you have a distinct particular action to handle the error.