Обрабатывать фатальные ошибки в PHP, используя register_shutdown_function ()

StackOverflow https://stackoverflow.com/questions/4410632

  •  08-10-2019
  •  | 
  •  

Вопрос

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

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

Кроме того, функции Backtrace Debug, кажется, несуществуют в функции отключения, что делает его совершенно бесполезной для регистрации трассировки стека, где произошла фатальная ошибка.

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

Это было полезно?

Решение

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

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.

Что касается обратной стороны, вы не можете ... :( В большинстве случаев фатальной ошибки, особенно Неопределенная функция Ошибки, вам это не нужно. Исправляя файл / строку, где это происходит, достаточно. Задний стол не имеет значения в этом случае.

Другие советы

Один из способов различать фатальную ошибку и надлежащим отключением приложения с помощью 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");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top