PHP: How to manage errors gracefully?

2020-04-10 04:05发布

问题:

When failed to access something on the web (api, database), how would I stop executing the rest of the script and log the error in the log file? Well, and so that the visitor wouldn't see the exact cause but rather they would see my custom message (say, 'A bad thing just happened'). What steps do I need to take to arrange things?

回答1:

I generally like using Exceptions, in that kind of situation : it allows me to have all error-handling code at one place.


For instance, I'd use something a bit like this :

try {
    // Some code

    // Some code that throws an exception

    // Some other code -- will not be executed when there's been an Exception

} catch (Exception $e) {
    // Log the technical error to file / database

    // Display a nice error message
}

With that, all error-handling code is in the catch block -- and not scatterred accros my whole application.


Note, though, that many PHP functions don't throw exceptions, and only raise a warning or an error...

For those, you could use set_error_handler to define your own error handler -- which could throw an Exception ;-)
For instance, see the example on the manual page of ErrorException.

Although this will work real fine for many errors/warnings, you should note that it will not work for Parse Error nor Fatal Error :

  • The first kind are actually raised before the PHP code is actually executed
  • And the second kind are... well... Fatal.


And I would never place any die nor exit in the middle of my code : that's, in my opinion, one of the worst possible way of dealing with errors.

I would also configure my server / application so :

  • Error messages are not displayed in the output, setting display_errors to Off.
  • Errors are logged to a file, using log_errors and error_log.


回答2:

and so that the visitor wouldn't see the exact cause but rather they would see my custom message

I would suggest you to go through this excellent article by David Walsh on custom error handling in PHP.

You can use set_error_handler() function for that.

how would I stop executing the rest of the script and log the error in the log file?

There is a default function of PHP to log errors; error_log

Example from PHP.net:

<?php
// Send notification through the server log if we can not
// connect to the database.
if (!Ora_Logon($username, $password)) {
    error_log("Oracle database not available!", 0);
    exit; //exit
}

// Notify administrator by email if we run out of FOO
if (!($foo = allocate_new_foo())) {
    error_log("Big trouble, we're all out of FOOs!", 1,
               "operator@example.com");
}

// another way to call error_log():
error_log("You messed up!", 3, "/var/tmp/my-errors.log");
?>

.

More Resources:

This is also good article covering most of it related to error handling.