Есть ли способ перенаправить на страницу с ошибкой в ​​register_shutdown_function?

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

Дело в том, что я хотел бы перенаправить на общую статическую страницу с ошибкой при возникновении критической ошибки (например: недоступность службы).

Как мне это сделать?

Отображать или использовать Javascript не представляется удовлетворительным решением.

Спасибо за вашу помощь !

Существует решение этого (обнаруживающее ошибки разбора), в отличие от того, что вы прочитали:

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

Обработка ошибок PHP с производством

Каждый файл PHP, который отображается на нашем веб-сайте, включает файл base.php, расположенный на один шаг выше каталога public_html /, поэтому идея заключалась в том, чтобы установить обработчик ошибок в самой верхней части base.php перед чем-либо еще:

base.php – вставьте это в начало своего кода:

 // НЕ ОКАЗЫВАЙТЕ ОШИБКИ ДЛЯ ПОЛЬЗОВАТЕЛЯ
 ini_set ("display_errors", 0);
 ini_set ("log_errors", 1);

 // Определите, куда вы хотите, чтобы журнал работал, syslog или файл по своему вкусу
 ini_set ("error_log", dirname (__ FILE __). '/ php_errors.log');

 register_shutdown_function (функция () {
     $ last_error = error_get_last ();
     if (! empty ($ last_error) && 
          $ last_error ['type'] & (E_ERROR | E_COMPILE_ERROR | E_PARSE | E_CORE_ERROR | E_USER_ERROR)
        )
     {
        require_once (имя_директории (__ FILE __) '/ public_html / maintenance.php'.);
        выход (1);
     }
 });

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

  include_once (имя_директории (__ FILE __) '/ public_html / Библиотека / foobar.php'.); 

Поэтому я пошел в foobar.php и сделал синтаксическую ошибку, превратив функцию … в удовольствие . Обычно будет отображаться ошибка или отображается белая страница, но из-за register_shutdown_function () на странице public_html / maintenance.php появляется сообщение с чем-то вроде:

Извините, в данный момент мы испытываем технические затруднения. Обновите эту страницу за несколько минут, чтобы узнать, разрешили ли мы проблему.

И, конечно же, пользователь понятия не имеет, что это «maintenance.php»,

Ура!

и я прочитал, что с использованием HTTP-заголовков в register_shutdown_function

Где вы это читали? Это не правильно. Все, что происходит в register_shutdown_function, не должно записываться обратно в браузер. В большинстве случаев выходной поток больше не будет доступен.

Я пытаюсь найти чистую для обработки фатальных ошибок

Тогда вы не можете сделать это с PHP-кодом – фатальный означает, что ваш PHP умер – он не может ничего сделать после ошибки.

Неустранимые ошибки вызваны

  • ошибки в вашем коде
  • ошибки в PHP
  • ошибки на веб-сервере

Последние 2 очень необычны – первая заключается в вашей ответственности за выявление и устранение. Хотя, как предлагает greOire, у вас должна быть своя собственная, заклейменная страница с ошибками (но читайте примечание о MSIE), это не поможет, когда ошибка возникнет после запуска вашего PHP-кода. И в этот момент веб-сервер предполагает, что код ответа будет 200 OK, если PHP не скажет ему что-то другое.

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

C.

Ответ symcbean верен в книге, но не всегда на практике. Несмотря на то, что вы не должны создавать выходные данные в обработчике выключения, вы можете сделать это при определенных обстоятельствах.

Проверьте headers_sent() . Проверьте свою функцию отключения. Если заголовки еще не отправлены, вы можете в случае необходимости повторить новые заголовки и фактический контент. Вы можете использовать error_get_last (), чтобы определить, вызвано ли выключение ошибкой или нет. Следующие типы ошибок являются несовместимыми и будут убивать функции сценария и выключения вызова:

  • E_ERROR
  • E_PARSE
  • E_CORE_ERROR
  • E_COMPILE_ERROR

Если тип ошибки является одним из них, а заголовки не отправлены, ваш обработчик выключения может создавать выходные данные, включая заголовки.

Вы не должны создавать выходные данные обработчика выключения, если отправлены заголовки . Эти заголовки могут включать Content-length и отправлять больше контента, чем вы сказали, что это плохо. Даже тогда, если отправлены заголовки, любой вывод, который вы создаете, может некуда идти, в зависимости от используемой версии PHP, базового программного обеспечения веб-сервера и того, является ли это FastCGI.

Фактически, этот ответ может быть полностью фиктивным вне mod_php и FastCGI на Apache 2.2.x. YMMV, но удачи.

Вы можете просто заменить страницу ошибки по умолчанию apache, используя директиву ErrorDocument: http://httpd.apache.org/docs/2.0/mod/core.html#errordocument