Catching PHP Errors

I’ve seen several tutorials on catching PHP errors that only mention how to catch one type of error – so here is a quick post with details of how to catch more.

Type 1. Most errors

This is the example you usually see in tutorials. Most errors can be caught by setting a custom error handler using the set_error_handler function. The example on the official PHP manual page is very long but here are the basics:

function error_handler($number, $message, $file, $line, $vars)  {  
     .... do something with error ... 
}
set_error_handler('error_handler');

Note the PHP process won’t die – after calling your error handler, it will carry on where it left off.

Type 2. Exceptions

You’ll also want to catch any exceptions using the set_exception_handler function. This time the example on the official manual page is short and to the point.

Type 3. Fatal Errors

Finally, how do you catch Fatal Errors? Because they are fatal, a custom error handler isn’t called. But you can do this:

function x() {
   $error = error_get_last();
   if ($error) {
      // deal with $error['file'],$error['line']
      // $error['message'],$error['type']
   }
}
register_shutdown_function('x');

This is called when PHP shuts down. It will only get the last error, but by definition a fatal error will be the last error to occur so that’s fine.

How do you know it doesn’t get the same error you may have seen earlier? It would be annoying to get the same error reported twice. Fortunately, errors you catch with a custom error handler won’t appear in the results of the error_get_last() function.

Note that what you can do in a shutdown script can be limited – PHP is shutting down after all. So don’t try anything fancy.

What to do with these errors?

Now we have caught these errors, what do we do with them? Ideally you want to log them, display a nice message to the user and email some developers. Which is one of several things our open source project does with errors – it also detects duplicates and lets you track errors in tickets. Have a look!

6 thoughts on “Catching PHP Errors”

  1. hi,

    a small notice on “Type 3. Fatal Errors” and “error_get_last()”:
    PHP-internal-Exceptions are hybrid (Exceptions and Errors)!

    1. if you throw own exceptions “error_get_last()” returns NULL
    2. if PHP throws (internal!) exceptions “error_get_last()” returns exception-data!

    so you end up logging catched exceptions/errors.

    Code:

    ini_set('display_errors', true);
    date_default_timezone_set('UTC');

    try {
    throw new Exception('crypto');
    } catch (Exception $e) {
    echo 'Exception: ' . var_export($e, true) . '';
    }

    echo 'error_get_last: ' . var_export(error_get_last(), true) . '';

    try {
    new DateTime('compress');
    } catch (Exception $e) {
    echo 'Exception: ' . var_export($e, true) . '';
    }

    echo 'error_get_last: ' . var_export(error_get_last(), true) . '';

    more info:
    http://de2.php.net/manual/en/errorfunc.configuration.php#ini.track-errors
    http://bugs.php.net/bug.php?id=54043

  2. hi,

    another very strange issue 🙂

    <?php

    function error($code, $message, $file = null, $line = 0) {
    echo "error_handler:n”;
    echo $message . ‘ – ‘ . $code;
    echo “”;
    throw new Exception($message, $code);
    }

    function shutdown() {
    echo “shutdown_function:n”;
    var_dump(error_get_last());
    echo “”;
    }

    #set_error_handler(‘error’);
    register_shutdown_function(‘shutdown’);

    try {
    echo $crypto->compress();
    } catch (Exception $e) { $t = $e->getTrace(); echo ‘Exception at ‘ . $t[0][‘file’] . ‘:’ . $t[0][‘line’] . “n”; }

    ^^ in code above, shutdown function is called.
    but if error handler is set, the Exception is swallowed and shutdown function is not called 🙂

    1. Well, there shouldn’t be any Exception, echo $crypto->compress(); generates an error not an exception, so the try/catch isn’t needed in that example.

      But I notice that in PHP 5.3.2, If there is an error handler set then the shutdown function is not called, and if there isn’t the shutdown function is called, as you say. Interesting.

  3. very interesting James, thanks for sharing. I will download & install your beta app and give it a try.

    what CAN you do when a FATAL error happens?
    (I assume you would not be able to save the error to a file, or send an email because php is shutting down.)

    1. You can actually do a lot, you can write to a file and I wouldn’t be surprised if you can send email tho I haven’t tried it myself. Let me know of any problems/feedback on the app!

Comments are closed.