# Catching all exceptions and errors in PHP

I've tried to catch all exceptions and errors in PHP in a way so that I can deal with them consistently.

This is the code with the exception of the very last bit where I instead pass $e on to a method that outputs an error page as HTML. // Only let PHP report errors in dev error_reporting(ENV === 'dev' ? E_ALL : 0); // Register handler set_error_handler("error_handler"); set_exception_handler("error_handler"); register_shutdown_function("error_handler"); function error_handler() { // Check for unhandled errors (fatal shutdown)$e = error_get_last();

// If none, check function args (error handler)
if($e === null)$e = func_get_args();

// Return if no error
if(empty($e)) return; // "Normalize" exceptions (exception handler) if($e[0] instanceof Exception)
{
call_user_func_array(__FUNCTION__, array(
$e[0]->getCode(),$e[0]->getMessage(),
$e[0]->getFile(),$e[0]->getLine(),
$e[0])); return; } // Create with consistent array keys$e = array_combine(array('number', 'message', 'file', 'line', 'context'),
array_pad($e, 5, null)); // Output error page var_dump($e);
exit;
}


I'm wondering if this is a decent way of doing it or if I have missed anything crucial. Any comments?

1. I don't think that printing raw errors/data to the users is a good idea:

var_dump(\$e);


They (usually) can't fix it, so it doesn't help them. (See #3 here) It might also contain sensitive information which could help attackers.

Instead of that you should log the errors to a log file, hide the details from the user (don't forget to print a friendly error message) and fix the errors. Your users might not call/mail you when they found a bug. They just simply use one of your competitor's service.

2. Instead of using the same function for three more or less different purposes:

set_error_handler("error_handler");
set_exception_handler("error_handler");
register_shutdown_function("error_handler");


I'd use three different functions (with proper signatures) which might call a fourth one. It would be cleaner (easier to read, understand and maintain). It would make unnecessary the internal magic with error_get_last(), func_get_args() and instanceof.

3. // Only let PHP report errors in dev
error_reporting(ENV === 'dev' ? E_ALL : 0);


It seems to me as a code smell: Test Logic in Production. I'd use php.ini to set this, I guess php.ini is a straightforward place for most of the PHP developers to set this instead of a PHP file.