In php, you can catch fatal errors using the register_shutdown_function() function.
First, add an βearlyβ fatal and error parser . It should go to index.php. The purpose of this code is to catch those errors that may occur before the controller has been started. Since we catch errors that may occur during application startup, it is better to use simple php without relying on any external libraries:
// Early fatal errors handler, it will be replaced by a full featured one in Controller class // (given it does not have any parse or fatal errors of its own) function earlyFatalErrorHandler($unregister = false) { // Functionality for "unregistering" shutdown function static $unregistered; if ($unregister) $unregistered = true; if ($unregistered) return; // 1. error_get_last() returns NULL if error handled via set_error_handler // 2. error_get_last() returns error even if error_reporting level less then error $error = error_get_last(); // Fatal errors $errorsToHandle = E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING; if ((!defined('APP_PRODUCTION_MODE') || APP_PRODUCTION_MODE) && !is_null($error) && ($error['type'] & $errorsToHandle)) { $message = 'FATAL ERROR: ' . $error['message']; if (!empty($error['file'])) $message .= ' (' . $error['file'] . ' :' . $error['line']. ')'; mail(' errors@YOURDOMAIN.COM ', $message, print_r($error, 1)); // Tell customer that you are aware of the issue and will take care of things // echo "Apocalypse now!!!"; } } register_shutdown_function('earlyFatalErrorHandler');
At this point, we still do not use the Yii error handler and do not register. To begin with, we need to register another shutdown function, which is part of our base controller, and can use the standard error handling and error logging provided by the Yii infrastructure (credits for this idea and most of the code go to the vital @ http: // habrahabr. com / post / 136138 / )
Please note that this function will notify about parsing errors if they do not analyze errors in the actual controller files, but in external files, such as models, helpers, views. If the parsing error is in the controller, the early handler will handle this.
In addition, this function allows you to display a more pleasant error page, rather than resetting the fatal error text or displaying a blank screen (if display_errors is turned off).
/** * Controller is the customized base controller class. * All controller classes for this application should extend from this base class. */ class Controller extends CController { // ... public function init() { register_shutdown_function(array($this, 'onShutdownHandler')); earlyFatalErrorHandler(true); // Unregister early hanlder } public function onShutdownHandler() { // 1. error_get_last() returns NULL if error handled via set_error_handler // 2. error_get_last() returns error even if error_reporting level less then error $error = error_get_last(); // Fatal errors $errorsToHandle = E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING; if (!is_null($error) && ($error['type'] & $errorsToHandle)) { // It better to set errorAction = null to use system view "error.php" instead of // run another controller/action (less possibility of additional errors) Yii::app()->errorHandler->errorAction = null; $message = 'FATAL ERROR: ' . $error['message']; if (!empty($error['file'])) $message .= ' (' . $error['file'] . ' :' . $error['line']. ')'; // Force log & flush as logs were already processed as the error is fatal Yii::log($message, CLogger::LEVEL_ERROR, 'php'); Yii::getLogger()->flush(true); // Pass the error to Yii error handler (standard or a custom handler you may be using) Yii::app()->handleError($error['type'], 'Fatal error: ' . $error['message'], $error['file'], $error['line']); } } // ... }