Friday, April 15, 2016

Get all PHP errors/warnings/… that occurred during the current request

Leave a Comment

Setting the directive display_errors to true (while having error_reporting set to E_ALL) prints all errors that occured during the current request bofore returing the PHP output.

Since I'm sending headers in my PHP code, I get several more errors (sending header after content has been sent is not possible).

Now I'd like to add the error messages to the end of my page. There I'd like to show all errors that occurred (until then). Unfortunately error_get_last only returns the last error that occurred.

I first thought that set_error_handler might solve the problem, but I'm afraid that my error-logging does not work anymore:

It is important to remember that the standard PHP error handler is completely bypassed for the error types specified by error_types unless the callback function returns FALSE.

Besides that:

The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

But maybe they are also not available in error_get_last()

So is there a way to print all errors after the output of the generated content?

5 Answers

Answers 1

There is a discussion about this here and here (amongst others), with the second answer on the latter list using a mix of set_error_handler() with register_shutdown_function() being a good solution.

Answers 2

Referring to your first concern: The error handling will still work as long as the:

callback function returns FALSE

function myErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {     // Do your stuff here, e.g. saving messages to an array      // Tell PHP to also run its error handler     return false; } 

One solution to store all error-numbers (in an outside array $error_list) could be:

$error_list = array();  $myErrorHandler = function ($error_level, $error_message, $error_file, $error_line, $error_context) use (&$error_list) {     $error_list[] = $error_level;     // Tell PHP to also run its error handler     return false; }; // Set your own error handler $old_error_handler = set_error_handler($myErrorHandler); 

Also see:

Answers 3

Fuller example that catches all the errors (exceptions and errors), pumps to a log file and remembers in a static class; at the end you query the static class to get the error.

I use similar to this for all projects to get full control over all errors.

function customErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {     ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, true); }  function nullErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {     ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, false); }  function customExceptionHandler($exception) {     if (is_a($exception, 'exceptionError')) {         echo $exception->output();     } else {         ErrorHandler(E_ERROR, $exception->getMessage() . '(' . $exception->getCode() . ')', $exception->getFile(), $exception->getLine(), null, true);     } }  function nullExceptionHandler($exception) {     if (is_subclass_of($exception, 'exceptionError')) {         $exception->output();     } else {         ErrorHandler(E_WARNING, $exception->getMessage() . '(' . $exception->getCode() . ')', $exception->getFile(), $exception->getLine(), null, false);     } }   function ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, $fatal) {     $errortype = array (             E_ERROR              => 'Error',             E_WARNING            => 'Warning',             E_PARSE              => 'Parsing Error',             E_NOTICE             => 'Notice',             E_CORE_ERROR         => 'Core Error',             E_CORE_WARNING       => 'Core Warning',             E_COMPILE_ERROR      => 'Compile Error',             E_COMPILE_WARNING    => 'Compile Warning',             E_DEPRECATED         => 'Deprecated',             E_USER_ERROR         => 'User Error',             E_USER_WARNING       => 'User Warning',             E_USER_NOTICE        => 'User Notice',             E_USER_DEPRECATED    => 'User Deprecated',             E_STRICT             => 'Runtime Notice',             E_RECOVERABLE_ERROR  => 'Catchable Fatal Error'             );       // Pushed into error log     if (error_reporting() > 0) {         $message = ': ' . $errmsg . ' in ' . $filename . ' on line ' . $linenum;         error_log('PHP ' . $errortype[$errno] . $message);          errorLogger::log($message);          if ($fatal) {             echo $errortype[$errno] . ': ' . $message;             exit();         }     } }   class errorLogger {      private static $aErrors = array();      // ******************* Timing functions *********************************      public static function log($message) {         self::$aErrors[] = $message;     }      public static function getErrors() {         return self::$aErrors;     }  } 

Usage Example

// Custom error handler. Can cope with the various call mechanisms $old_error_handler = set_error_handler('nullErrorHandler'); $old_exception_handler = set_exception_handler('nullExceptionHandler');  // Do your stuff // * // * // * // * // *  $old_error_handler = set_error_handler('customErrorHandler');   // Set to 'nullErrorHandler' to allow it to continue $old_exception_handler = set_exception_handler('customExceptionHandler');   // Set to 'nullExceptionHandler' to allow it to continue  // At end $errors = errorLogger::getErrors(); foreach($errors as $errorMessage) {     echo $errorMessage; } 

Answers 4

Catch the errors as you go and output messages at the end.

<?php  $errors = []; try{       // code to test } catch(\Exception $e) {   $errors[] = $e->getMessage; } try{       // next bit of code to test } catch(\Exception $e) {   $errors[] = $e->getMessage; } ...  // display all messages at the end echo "\n<pre><code>\n"; print_r($errors); echo "\n</code></pre>\n"; 

Answers 5

 ini_set('display_errors', 1);  ini_set('display_startup_errors', 1);  error_reporting(E_ALL);    or    set your php.ini with this line:    display_errors=on 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment