Table of Contents
Typical PHP Script errors and their default Action
In the following POST we will have a closer look at the following PHP Script Errors Value Constant Description 1 E_ERROR Fatal run-time errors. Errors that cannot be recovered from. Execution of the script is halted 4 E_PARSE Compile-time parse errors. Parse errors should only be generated by the parser. Script is halted. 8 E_NOTICE Run-time notices. The script found something that might be an error, but could also happen when running a script normaly . Script runs to the END.
Is using set_error_handler() a working solution ?
- 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.
- Using set_error_handler is only useful for debugging Warnings [ like uninitialised variables ]
- If using a user function (error_handler) to handle errors in a script by using set_error_handler() any WARNING will not get displayed in our register_shutdown_function() at the PHP page end. This is not expected !
- As set_error_handler() can’t be used for all errors we should use register_shutdown_function instead
Using register_shutdown_function() to handle PARSE, RUNTIME and WARNINGS
- Parse Errors can only be handled by using register_shutdown_function in the top level PHP Page
- PHP shutdownhandler() uses error_get_last() to retrieve the latest PHP error/warning
- NOTE: YOU should disable any error handler ( set by set_error_handler() ) if you want to log even WARNING messages.
PHP Code for our TOP LEVEL Page
<?php include 'phpErrorHandler.php'; /* defines errorHandler and shutdownHandler function */ // set_error_handler("errorHandler"); /* disable _error_handler when using register_shutdown_function */ /* If set_error_handler() is enabled WARNIGNS will be missed in our registered shutdown function*/ register_shutdown_function("shutdownHandler"); ini_set('display_errors', false); /* Note PHP errors may break the JSON traffic in our AJAX requests */ /* Don't to display any Errors in the Browser Window */ ini_set('error_reporting', E_ALL); $handlerType='TOP LEVEL'; echo "<p>____Before Error::</p>"; include 'create_a_php_error.php'; /* The PHP source with an errors */ /* Note we will never reach this line in case of syntax errors in create_a_php_error.php */ echo "<p>____After Include:: </p>"; runme(); /* The function with an error */ echo "<p>____Leaving Page:: </p>"; ?>
PHP Code for our shutdownHandler
<?php function shutdownHandler() //will be called when php script ends. { global $handlerType; logError(" -------------- Inside shutdownHandler: ".$handlerType." -----------------------", "info"); $lasterror = error_get_last(); if ( $lasterror === null ) logError('[SHUTDOWNHANDLER]:: No errors found in PHP Page',"info"); else { // logError('[SHUTDOWNHANDLER]:: Found errors found in PHP Page: - Error Type:: '.$lasterror['type'] ,"info"); switch ($lasterror['type']) { case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: case E_RECOVERABLE_ERROR: case E_CORE_WARNING: case E_COMPILE_WARNING: case E_PARSE: { $error = "[SHUTDOWNHANDLER] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line']; // echo '<p><b>'.$error.'</b></p>'; logError($error, "fatal"); break; } default: { $error = "[SHUTDOWNHANDLER: Unknown Type ] LVL:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line']; logError($error, "fatal"); } } } } function logError($error, $errlvl) { error_log($error); /* Write to PHP error log */ echo '<p><b>'.$error.'<b></p>'; /* Display the error in our PHP page */ } ?>
PHP Code to be tested – Runtime Warning – throws E_NOTICE error
<?php function runme() { global $handlerType; $handlerType ='2nd LEVEL'; echo "<p><b>function runme():: This function creates a PHP Warning , PHP Runtime Error or PHP Syntax Error ! </b></p>"; /* Error1 : Runtime Warning - throws E_NOTICE error */ echo $test; echo "<p>Leaving function runme - Now dying !</p>"; die(); } ?> HTML Output: ____Before Error:: ____After Include:: function runme():: This function creates a PHP Warning , PHP Runtime Error or PHP Syntax Error ! Leaving function runme - Now dying ! -------------- Inside shutdownHandler: 2nd LEVEL ----------------------- [SHUTDOWNHANDLER: Unknown Type ] LVL:8 | msg:Undefined variable: test | file:D:\xampp\htdocs\create_a_php_error.php | ln:23 PHP Log : [29-Nov-2015 18:16:31 Europe/Berlin] PHP Notice: Undefined variable: test in D:\xampp\htdocs\create_a_php_error.php on line 23 [29-Nov-2015 18:16:31 Europe/Berlin] -------------- Inside shutdownHandler: 2nd LEVEL ----------------------- [29-Nov-2015 18:16:31 Europe/Berlin] [SHUTDOWNHANDLER: Unknown Type ] LVL:8 | msg:Undefined variable: test | file:D:\xampp\htdocs\create_a_php_error.php | ln:23
- As we get only E_NOTICE Warning the script runs to the end
- Our PAGE SHUTDOWNHANDLER is able to retrieve this WARNING
PHP Code to be tested – Fatal Runtime error : E_ERROR
<?php function runme() { global $handlerType; $handlerType ='2nd LEVEL'; echo "<p><b>function runme():: This function creates a PHP Warning , PHP Runtime Error or PHP Syntax Error ! </b></p>"; /* Error2 : Runtime Error - throws E_ERROR */ echo "<p>Curent Working directory: ".getcd() . "</p>"; echo "<p>Leaving function runme - Now dying !</p>"; die(); } ?> HTML Output: ____Before Error:: ____After Include:: function runme():: This function creates a PHP Warning , PHP Runtime Error or PHP Syntax Error ! -------------- Inside shutdownHandler: 2nd LEVEL ----------------------- [SHUTDOWNHANDLER] lvl:1 | msg:Call to undefined function getcd() | file:D:\xampp\htdocs\create_a_php_error.php | ln:26 PHP Error LOG: [29-Nov-2015 18:24:09 Europe/Berlin] PHP Fatal error: Call to undefined function getcd() in D:\xampp\htdocs\create_a_php_error.php on line 26 [29-Nov-2015 18:24:09 Europe/Berlin] -------------- Inside shutdownHandler: 2nd LEVEL ----------------------- [29-Nov-2015 18:24:09 Europe/Berlin] [SHUTDOWNHANDLER] lvl:1 | msg:Call to undefined function getcd() | file:D:\xampp\htdocs\create_a_php_error.php | ln:26
- Note this script was aborted due to fatal E_ERROR error
PHP Code to be tested – Fatal PARSE error : E_PARSE
<?php function runme() { global $handlerType; $handlerType ='2nd LEVEL'; echo "<p><b>function runme():: This function creates a PHP Warning , PHP Runtime Error or PHP Syntax Error ! </b></p>"; /* Error 3: Syntax error - throws E_PARSE : this is a fatal error an can only handled in the TOP level PHP page */ logS( echo "<p>Leaving function runme - Now dying !</p>"; die(); } ?> HTML Output: ____Before Error:: -------------- Inside shutdownHandler: TOP LEVEL ----------------------- [SHUTDOWNHANDLER] lvl:4 | msg:syntax error, unexpected 'echo' (T_ECHO) | file:D:\xampp\htdocs\create_a_php_error.php | ln:31 PHP Error LOG: [29-Nov-2015 18:31:07 Europe/Berlin] PHP Parse error: syntax error, unexpected 'echo' (T_ECHO) in D:\xampp\htdocs\create_a_php_error.php on line 31 [29-Nov-2015 18:31:07 Europe/Berlin] -------------- Inside shutdownHandler: TOP LEVEL ----------------------- [29-Nov-2015 18:31:07 Europe/Berlin] [SHUTDOWNHANDLER] lvl:4 | msg:syntax error, unexpected 'echo' (T_ECHO) | file:D:\xampp\htdocs\create_a_php_error.php | ln:31
- Note this script was aborted due to fatal E_PARSE error
- Only if we have registered a SHUTDOWNHANDLER in our top level page we can catch this type of PARSE errors