I'm confused about how to use set_error_handler() properly, and the php documentation isn't really helping to clarify.
I want it to email me as many errors as possible, with the exception of notices.
<?php
if (TRAP_ERRORS) {
// True on production, false in development, where errors are just echoed out.
set_exception_handler('globalExceptionHandler');
set_error_handler('globalErrorHandler', E_USER_WARNING);
}
function globalExceptionHandler($e) {
//log and email stuff here
}
function globalErrorHandler($errno, $errstr, $errfile, $errline) {
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
$errors = "Notice";
break;
case E_WARNING:
case E_USER_WARNING:
$errors = "Warning";
break;
case E_ERROR:
case E_USER_ERROR:
$errors = "Fatal Error";
break;
default:
$errors = "Unknown Error";
break;
}
error_log(sprintf("PHP %s: %s in %s on line %d", $errors, $errstr, $errfile, $errline));
$msg = "ERROR: [$errno] $errstr\r\n".
"$errors on line $errline in file $errfile\r\n";
sendErrorEmail($msg);
showErrorPage();
exit(1);
}
function sendErrorEmail($p_errorMsg) {
// Parse and sent out the error email...
}
function showErrorPage() {
// Redirect to an error page.
}
?>
Above is my current setting set_error_handler('globalErrorHandler', E_USER_WARNING);
, which seems to be wrong in that it doesn't cover trigger_error() errors. I believe that is because the argument is supposed to be a bitmask instead of just a single error level, but I am not sure how to set it to work for the maximum number of errors/information (except notices). I've seen examples that use E_ALL
, but that actually directly causes any code that includes the global error handler stuff to error for me.
So anyway, how do I use set_error_handler so that the maximum amount of information can be handled by my custom error handler (so that I can get automatic emails directly when such problems occur, instead of having to review the logs later).
The set_error_handler() function sets a user-defined error handler function. Note: The standard PHP error handler is completely bypassed if this function is used, and the user-defined error handler must terminate the script, die(), if necessary.
You can "catch" these "fatal" errors by using set_error_handler() and checking for E_RECOVERABLE_ERROR. I find it useful to throw an Exception when this error is caught, then you can use try/catch.
set_error_handler('some_handler',E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
Or, if you really want all,
set_error_handler('some_handler',-1 & ~E_NOTICE & ~E_USER_NOTICE);
Alternatively, you can just set it to use all errors, and just ignore it if they're not in error_reporting
(which you set to the same value as the above line, also, the @
operator works then):
....
if(!($errno & error_reporting())) return true;
switch($errno){
....
Leave out the second parameter or pass in the default E_ALL | E_STRICT
(all errors AND strictness errors, don't be confused by the bitwise OR
here)
Additionally you can 'catch' Fatal errors
by doing a register_shutdown_function()
and error_get_last()
trick demonstrated here: Handle fatal errors in PHP using register_shutdown_function()
The $error_type
is an integer which you set using masking. To use an error handler for everything except E_NOTICE you'd use one of the following:
set_error_handler('globalErrorHandler', E_ALL ^ E_NOTICE);
set_error_handler('globalErrorHandler', E_ALL & ~E_NOTICE);
If you want to also exclude E_USER_NOTICE then:
set_error_handler('globalErrorHandler', E_ALL ^ (E_NOTICE | E_USER_NOTICE));
set_error_handler('globalErrorHandler', E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
Note the use of the bitwise operators "&", "~" and "|", see PHP Bitwise operator manual.
Be careful, some errors will not be picked up if they occur before your set_error_handler call, or are compiler errors (unlikely, but who knows). See PHP set_error_handler documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With