set_error_handler() не работает для ФАТАЛЬНОЙ ошибки

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

это работает для всего, но не срабатывает из-за фатальной ошибки.

Любой способ решить это?

В настоящее время, чтобы обойти это обстоятельство, я также зарегистрировал функцию отключения, которая проверяет error_get_last()


person dynamic    schedule 15.12.2011    source источник


Ответы (3)


Нет, это просто ограничение set_error_handler(); он не обрабатывает все ошибки.

Следующие типы ошибок не могут быть обработаны пользовательской функцией: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT возникает в файле, где вызывается set_error_handler().

register_shutdown_function() и error_get_last() — достойный обходной путь.

person alex    schedule 15.12.2011
comment
Можете ли вы привести пример использования register_shutdown_function() и error_get_last() в качестве обходного пути, который я не могу придумать. - person Roman Toasov; 21.11.2016

Есть только хакерские способы решить эту проблему, например. используя register_shutdown_function(), а затем проверяя, произошла ли ошибка внутри этой функции.

PHP имеет log_errors по какой-то причине, вы можете заставить PHP регистрировать любую ошибку в системном журнале или файле журнала без единой строки пользовательского кода. Поэтому использование set_error_handler() для этой цели вообще не нужно и должно следует избегать, если вам не нужно, например трассировка стека.

person ThiefMaster    schedule 15.12.2011
comment
конечно, мне нужна трассировка стека и/или другая отладочная информация, как описано в моем первом посте. - person dynamic; 16.12.2011

Как указывали другие, мы можем использовать register_shutdown_function() и error_get_last() следующим образом.

В приведенной ниже реализации будут обнаружены ошибки, которые даже не обнаружены \Throwable, как это было протестировано в php 7.1. Это должно работать и для предыдущих версий PHP. Это должно быть реализовано только в вашей среде разработки (просто добавив его в файл конфигурации разработки) и не должно выполняться в производственной среде.

Выполнение

register_shutdown_function(function () {
    $err = error_get_last();
    if (! is_null($err)) {
        print 'Error#'.$err['message'].'<br>';
        print 'Line#'.$err['line'].'<br>';
        print 'File#'.$err['file'].'<br>';
    }
});

Пример ошибки

Error# Class Path/To/MyService contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Path/To/MyServiceInterface::add)
Line# 12
File# Path/To/MyService.php
person Kamal Soni    schedule 16.10.2018
comment
есть ли способ возобновить код, когда произошла фатальная ошибка? для ошибки говорит, что какая-то функция не определена. я хочу определить эту функцию с помощью eval() и возобновить мой код до следующей ошибки. это возможно? - person Ahmad Ameri; 29.07.2020
comment
@AhmadAmeri К сожалению, невозможно продолжить после фатальной ошибки в PHP. Вы можете поймать их только с помощью этого хака и систематически удалять их по мере их появления. - person Kamal Soni; 31.07.2020