Intereting Posts
PHP-печать на локальный термальный принтер не работает без имени сети Изображение php captcha не отображается Используйте mysql_fetch_array () вместо foreach () вместо while () Как сделать SELECT в PHP / MySQL нечувствительным? Загрузка php и ошибка внутреннего сервера PHP: «Декларация … должна быть совместима с тем …» добавить разрыв строки между двумя переменными Лучший способ хранения & (Амперсанд) в базе данных MySQL Поиск подмножеств массива в PHP Как следует анализировать фоновые изображения PHP (простой html dom parser) и другие изображения веб-страницы? «Начинается с» в шаблоне Twig Каков синтаксис сортировки коллекции Eloquent несколькими столбцами? Как отслеживать время выполнения каждой строки / блока строк / методов в PHP? PHP Функция по умолчанию Значения параметров, как «передать значение по умолчанию» для «не последних» параметров? Формат даты MySQL

Управлять фатальными ошибками в PHP с помощью register_shutdown_function ()

Согласно комментарию к этому ответу, можно поймать Fatal Errors через функцию выключения, которую невозможно поймать с помощью set_error_handler() .

Тем не менее, я не мог узнать, как определить, произошло ли завершение из-за фатальной ошибки или из-за того, что скрипт достиг своего конца.

Кроме того, функции отладки backgrace, по-видимому, не работают в функции выключения, что делает его довольно бесполезным для регистрации трассировки стека, где произошла Fatal Error.

Поэтому мой вопрос: какой лучший способ реагировать на Fatal Errors (особенно неопределенные вызовы функций), сохраняя при этом способность создавать правильную обратную линию?

Это работает для меня:

 function shutdown() { $error = error_get_last(); if ($error['type'] === E_ERROR) { // fatal error has occured } } register_shutdown_function('shutdown'); spl_autoload_register('foo'); // throws a LogicException which is not caught, so triggers a E_ERROR 

Тем не менее, вы, вероятно, знаете это уже, но просто для того, чтобы убедиться: вы никак не можете восстановить E_ERROR.

Что касается backtrace, вы не можете … 🙁 В большинстве случаев фатальной ошибки, особенно ошибок Undefined , вам это действительно не нужно. Точное определение файла / строки, где она происходила, является достаточной. в таком случае.

Один из способов отличить фатальную ошибку и правильное закрытие приложения с помощью функции register_shutdown_function – определить константу в качестве последней строки вашей программы, а затем проверить, определена ли константа:

 function fatal_error() { if ( ! defined(PROGRAM_EXECUTION_SUCCESSFUL)) { // fatal error has occurred } } register_shutdown_function('fatal_error'); define('PROGRAM_EXECUTION_SUCCESSFUL', true); 

Если программа достигает конца, она не могла бы столкнуться с фатальной ошибкой, поэтому мы знаем, что она не запускает функцию, если константа определена.

error_get_last () – это массив со всей информацией о фатальной ошибке, которую необходимо отлаживать, хотя она не будет иметь обратную трассировку, как уже упоминалось.

Как правило, если ваша php-программа столкнулась с фатальной ошибкой (в отличие от исключения), вы хотите, чтобы программа взорвалась, чтобы вы могли найти и устранить проблему. Я нашел register_shutdown_function полезным для производственных сред, где вы хотите, чтобы отчет об ошибках отключился, но хотите каким-то образом зарегистрировать ошибку в фоновом режиме, чтобы вы могли ответить на нее. Вы также можете использовать эту функцию, чтобы направить пользователя на дружественную html-страницу в случае такой ошибки, чтобы вы не просто отображали пустую страницу.

Просто хороший трюк, чтобы получить текущий метод error_handler =)

 <?php register_shutdown_function('__fatalHandler'); function __fatalHandler() { $error = error_get_last(); //check if it's a core/fatal error, otherwise it's a normal shutdown if($error !== NULL && $error['type'] === E_ERROR) { //Bit hackish, but the set_exception_handler will return the old handler function fakeHandler() { } $handler = set_exception_handler('fakeHandler'); restore_exception_handler(); if($handler !== null) { call_user_func($handler, new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line'])); } exit; } } ?> 

Также я не буду замечать, что если вы позвоните

 <?php ini_set('display_errors', false); ?> 

Php перестает отображать ошибку, иначе текст ошибки будет отправлен клиенту до вашего обработчика ошибок

Для этого я использую «ob_start».

 function fatal_error_handler($buffer) { if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs) ) { //Your code } return $buffer; } ob_start("fatal_error_handler");