6
\$\begingroup\$

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?

asked Jun 3, 2013 at 23:47
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
  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.

answered Mar 24, 2014 at 0:06
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.