Предотвращение вывода обратной трассировки фатальных ошибок PHP при использовании пользовательского обработчика завершения работы

Я должен что-то упустить в моем понимании обработки ошибок PHP, в частности, подавления их вывода. Когда происходит фатальная ошибка, я ожидаю, что моя функция обработчика выключения корректно обработает ее и завершит выполнение скрипта. Это работает, как ожидалось. Однако я не могу запретить PHP выводить информацию о фатальной ошибке.

Мой файл php.ini содержит следующие директивы:

error_reporting = E_ALL | E_STRICT
display_errors = Off

Я установил error_reporting , чтобы сообщать обо всем, и я использую специальный обработчик ошибок, чтобы генерировать исключения. Я ожидаю, что display_errors = Off предотвратит отображение ЛЮБЫХ сообщений об ошибках.

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

Теперь перейдем к моему упрощенному коду:

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'Off');

function shutdown_handler()
{
  $err = error_get_last();
  $fatal = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR);
  if ($err && in_array($err['type'], $fatal)) {
    echo "\n\ntest fatal error output\n\n";
  }
  exit();
}

register_shutdown_function('shutdown_handler');

Чтобы проверить его, я генерирую фатальную ошибку «Допустимый размер памяти исчерпан», например:

// max out available memory
$data = '';
while(true) {
  $data .= str_repeat('#', PHP_INT_MAX);
}

Поскольку у меня display_errors = Off , я ожидаю, что это будет выдает только следующий вывод (согласно обработчику выключения):

test fatal error output

Но вместо этого я продолжаю получать:

PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 2147483648 bytes) in /home/daniel/mydev/php/test0.php on line 24
PHP Stack trace:
PHP   1. {main}() /home/daniel/mydev/php/test0.php:0
PHP   2. str_repeat() /home/daniel/mydev/php/test0.php:24

test fatal error output

Что мне не хватает, что предотвратит вывод этой трассировки ошибки?


ЗАКЛЮЧЕНИЕ

Похоже, как @Cthos мудро заметил, что «E_ERROR и display_errors несовместимы друг с другом."

Это также относится к E_PARSE (и я предполагаю, что E_CORE_ERROR / E_COMPILE_ERROR, но я не нарушал мою установку PHP, чтобы проверить ее). Я полагаю, имеет смысл, что PHP в этих случаях принудительно запускает трассировку ошибки в STDOUT потому что, если бы это было не так, вы никогда не узнаете, что / почему что-то пошло не так.

Итак, решение в этом случае было бы:

  1. Как предложил @Cthos, отключить уведомления E_ERROR в php.ini: error_reporting = (E_ALL & ~ E_ERROR) или во время выполнения с использованием error_reporting (E_ALL & ~ E_ERROR);
  2. Обновите обработчик завершения работы, чтобы проверить, была ли последняя ошибка типа E_ERROR, и выполнить соответствующие действия, если это так.

Что касается других фатальных ошибок, таких как E_PARSE, E_CORE_ERROR и т. Д., Вам просто нужно убедиться, что ваш код правильный и что ваш PHP работает. Если вы попытаетесь заглушить ошибки E_PARSE и обработать их в своей функции выключения, это не сработает. потому что ошибки синтаксического анализа не позволяют PHP зайти так далеко.

Итак, обновленный / рабочий обработчик завершения работы выглядит вроде этого:

error_reporting(E_ALL & ~ E_ERROR);

function shutdown_handler()
{
  $err = error_get_last();
  if ($err && $err['type'] == E_ERROR) {
    $msg = 'PHP Fatal Error: '.$err['message'].' in '.$err['file'].
      ' on line '.$err['line'];
    echo $msg, PHP_EOL;
  }
  exit();
}
10
задан hakre 18 April 2013 в 16:55
поделиться