Na navigaci | Klávesové zkratky

How to write error handler in PHP?

When writing your own error handler for PHP, it is absolutely necessary to follow several rules. Otherwise, it can disrupt the behavior of other libraries and applications that do not expect treachery in the error handler.

Parameters

The signature of the handler looks like this:

function errorHandler(
    int $severity,
    string $message,
    string $file,
    int $line,
    array $context = null // only in PHP < 8
): ?bool {
    ...
}

The $severity parameter contains the error level (E_NOTICE, E_WARNING, …). Fatal errors such as E_ERROR cannot be caught by the handler, so this parameter will never have these values. Fortunately, fatal errors have essentially disappeared from PHP and have been replaced by exceptions.

The $message parameter is the error message. If the html_errors directive is enabled, special characters like < are written as HTML entities, so you need to decode them back to plain text. However, beware, some characters are not written as entities, which is a bug. Displaying errors in pure PHP is thus prone to XSS.

The $file and $line parameters represent the name of the file and the line where the error occurred. If the error occurred inside eval(), $file will be supplemented with this information.

Finally, the $context parameter contains an array of local variables, which is useful for debugging, but this has been removed in PHP 8. If the handler is to work in PHP 8, omit this parameter or give it a default value.

Return Value

The return value of the handler can be null or false. If the handler returns null, nothing happens. If it returns false, the standard PHP handler is also called. Depending on the PHP configuration, this can print or log the error. Importantly, it also fills in internal information about the last error, which is accessible by the error_get_last() function.

Suppressed Errors

In PHP, error display can be suppressed either using the shut-up operator @ or by error_reporting():

// suppress E_USER_DEPRECATED level errors
error_reporting(~E_USER_DEPRECATED);

// suppress all errors when calling fopen()
$file = @fopen($name, 'r');

Even when errors are suppressed, the handler is still called. Therefore, it is first necessary to verify whether the error is suppressed, and if so, we must end our own handler:

if (!($severity & error_reporting())) {
    return false;
}

However, in this case, we must end it with return false, so that the standard error handler is still executed. It will not print or log anything (because the error is suppressed), but ensures that the error can be detected using error_get_last().

Other Errors

If our handler processes the error (for example, displays its own message, etc.), there is no need to call the standard handler. Although then it will not be possible to detect the error using error_get_last(), this does not matter in practice, as this function is mainly used in combination with the shut-up operator.

If, on the other hand, the handler does not process the error for any reason, it should return false so as not to conceal it.

Example

Here's what the code for a custom error handler that transforms errors into ErrorException exceptions might look like:

set_error_handler(function (int $severity, string $message, string $file, int $line) {
    if (!(error_reporting() & $severity)) {
        return false;
    }

    throw new \ErrorException($message, 0, $severity, $file, $line);
});

4 years ago in section PHP | blog written by David Grudl | back to top

You might be interested in

Leave a comment

Text of the comment
Contact

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--

phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.