Есть ли способ для электронной почты / регистрации php фатальных ошибок, происходящих в проекте на основе структуры Yii?
Например, можно настроить Yii на отправку сообщений об ошибках «неопределенной переменной», но фатальные могут отслеживаться только отдельным, не интегрированным в код рамки, который не идеален.
В php можно перехватить фатальные ошибки, используя функцию register_shutdown_function()
.
Во-первых, давайте добавим «ранний» фатальный и обработчик ошибок анализа . Он должен идти в index.php. Цель этого кода – уловить те ошибки, которые могут произойти до того, как контроллер был запущен. Поскольку мы ловим ошибки, которые могут возникнуть во время запуска приложения, лучше использовать простой php, не полагаясь на какие-либо внешние библиотеки:
// 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');
На этом этапе мы все еще не используем обработчик ошибок Yii и не регистрируем. Для начала нам нужно зарегистрировать еще одну функцию выключения, которая является частью нашего базового контроллера, и может использовать стандартную обработку ошибок и протоколирование ошибок, предоставляемое инфраструктурой Yii (кредиты для этой идеи и большая часть кода переходят к жизненно важным @ http: // habrahabr. ru / post / 136138 / )
Обратите внимание, что эта функция будет уведомлять об ошибках синтаксического анализа, если они не являются ошибками разбора в фактических файлах контроллера, а во внешних файлах, таких как модели, помощники, представления. Если ошибка синтаксического анализа находится в контроллере, обработчик будет иметь дело с ним.
Также эта функция позволяет отображать более качественную страницу с ошибкой, вместо того, чтобы сбрасывать фатальный текст ошибки или показывать пустой экран (если display_errors выключен).
/** * 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's 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']); } } // ... }