Я могу использовать set_error_handler()
для перехвата большинства ошибок PHP, но это не работает для E_ERROR
ошибок fatal ( ), таких как вызов функции, которая не существует. Есть ли другой способ отловить эти ошибки?
Я пытаюсь вызвать mail()
все ошибки и использую PHP 5.2.3.
php
fatal-error
слишком много PHP
источник
источник
Ответы:
Регистрируйте фатальные ошибки, используя
register_shutdown_function
PHP 5.2+:Вы должны определить
error_mail
иformat_error
функции. Например:Используйте Swift Mailer, чтобы написать
error_mail
функцию.Смотрите также:
источник
mail("myname@myemail.com", "My Site: FATAL ERROR", "Details: " . $errno . ' ' . $errstr . ' ' . $errfile . ' ' . $errline);
Я только что придумал это решение (PHP 5.2.0+):
Различные типы ошибок определены в предопределенных константах .
источник
If an error handler (see set_error_handler ) successfully handles an error then that error will not be reported by this function.
"register_shutdown_function()
должен быть раньше, чем любая фатальная ошибка.use_1T_memory(); /* memory exhausted error here! */ register_shutdown_function('shutDownFunction');
не будет работать, как ожидалось.PHP не предоставляет традиционных средств для обнаружения и восстановления после фатальных ошибок. Это потому, что обработка не должна быть восстановлена после фатальной ошибки. Строка, совпадающая с выходным буфером (как предложено в оригинальном посте, описанном на PHP.net), определенно не рекомендуется. Это просто ненадежно.
Вызов функции mail () из метода обработчика ошибок также оказывается проблематичным. Если бы у вас было много ошибок, ваш почтовый сервер был бы загружен работой, и вы могли бы оказаться с мрачным почтовым ящиком. Чтобы избежать этого, вы можете использовать cron для периодического сканирования журналов ошибок и соответствующей отправки уведомлений. Вам также может понравиться программное обеспечение для мониторинга системы, такое как Nagios .
Чтобы немного рассказать о регистрации функции выключения:
Это правда, что вы можете зарегистрировать функцию выключения, и это хороший ответ.
Дело в том, что мы обычно не должны пытаться восстанавливаться после фатальных ошибок, особенно не используя регулярное выражение для вашего выходного буфера. Я отвечал на принятый ответ , который связан с предложением на php.net, которое с тех пор было изменено или удалено.
Это предложение заключалось в том, чтобы использовать регулярное выражение для выходного буфера во время обработки исключений, а в случае фатальной ошибки (обнаруженной при сопоставлении с любым сконфигурированным текстом ошибки, который вы могли ожидать) попытаться выполнить какое-либо восстановление или продолжить обработку. Это не было бы рекомендуемой практикой (я полагаю, поэтому я не могу найти оригинальное предложение тоже. Я либо пропускаю его, либо сообщество php сняло его).
Возможно, стоит отметить, что более поздние версии PHP (около 5.1), по-видимому, вызывают функцию выключения раньше, до вызова обратного вызова буферизации вывода. В версии 5 и более ранних версиях этот порядок был обратным (за обратным вызовом буферизации вывода следовала функция выключения). Кроме того, начиная с версии 5.0.5 (что намного раньше, чем версия 5.2.3 опрашивающего), объекты выгружаются задолго до вызова зарегистрированной функции выключения, поэтому вы не сможете полагаться на объекты в памяти для выполнения много всего
Таким образом, регистрация функции выключения - это хорошо, но задачи, которые должны выполняться с помощью функции выключения, вероятно, ограничены горсткой простых процедур выключения.
Ключ к выводу здесь - это всего лишь несколько слов мудрости для любого, кто наткнется на этот вопрос и увидит совет в первоначально принятом ответе. Не проверяйте свой выходной буфер.
источник
Что ж, кажется возможным поймать фатальные ошибки другим способом :)
источник
Фатальные ошибки или исправимые фатальные ошибки теперь генерируют экземпляры
Error
в PHP 7 или более поздних версиях . Как и любые другие исключения,Error
объекты могут быть перехвачены с помощьюtry/catch
блока.Пример:
https://3v4l.org/67vbk
Или вы можете использовать
Throwable
интерфейс, чтобы перехватить все исключения.Пример:
https://3v4l.org/Br0MG
Для получения дополнительной информации: http://php.net/manual/en/language.errors.php7.php
источник
Fatal error: Trait 'FailedTrait' not found in
при использованииReflectionClass
?include "filename.php"
вместо этого вtry
блок, а затемThrowable
блок catch работает как минимумParseError
.Я разработал способ отловить все типы ошибок в PHP (почти все)! Я не уверен насчет E_CORE_ERROR (думаю, не будет работать только для этой ошибки)! Но для других фатальных ошибок (E_ERROR, E_PARSE, E_COMPILE ...) отлично работает, используя только одну функцию обработчика ошибок! Там идет мое решение:
Поместите следующий код в ваш основной файл (index.php):
источник
Вы не можете ловить / обрабатывать фатальные ошибки, но вы можете регистрировать / сообщать о них. Для быстрой отладки я изменил один ответ на этот простой код
источник
Вы не можете выбросить исключение внутри зарегистрированной функции отключения, например:
Но вы можете перехватить и перенаправить запрос на другую страницу.
источник
Если вы используете PHP> = 5.1.0 Просто сделайте что-то подобное с классом ErrorException:
источник
Хорошее решение найдено в Zend Framework 2:
Этот класс позволяет вам запускать определенные
ErrorHandler
иногда, если вам это нужно. И тогда вы также можете остановить обработчик.Используйте этот класс, например, так:
Ссылка на полный код класса:
https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/ErrorHandler.php
Возможно, лучшим решением будет то, что от Monolog :
Ссылка на полный код класса:https://github.com/Seldaek/monolog/blob/master/src/Monolog/ErrorHandler.php
Он также может обрабатывать FATAL_ERRORS с помощью
register_shutdown_function
функции. Согласно этому классу FATAL_ERROR является одним из следующихarray(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)
.источник
Мне нужно обработать фатальные ошибки для производства, чтобы вместо этого показать статический стиль 503 Сервис недоступен вывод HTML. Это, безусловно, разумный подход к «выявлению фатальных ошибок». Вот что я сделал:
У меня есть пользовательская функция обработки ошибок «error_handler», которая будет отображать мою HTML-страницу «503 service unavailable» на любом E_ERROR, E_USER_ERROR и т. Д. Теперь она будет вызываться для функции выключения, улавливая мою фатальную ошибку,
в моей пользовательской функции error_handler, если ошибка E_ERROR, E_USER_ERROR и т. д. Я также вызываю
@ob_end_clean();
очистить буфер, удаляя таким образом PHP-сообщение «фатальная ошибка».Обратите внимание на строгие функции проверки и
@
выключения isset (), поскольку мы не хотим, чтобы наши скрипты error_handler генерировали какие-либо ошибки.Все еще соглашаясь с keparo, обнаружение фатальных ошибок лишает цели «ФАТАЛЬНОЙ ошибки», поэтому на самом деле вы не собираетесь выполнять дальнейшую обработку. Не запускайте никакие функции mail () в этом процессе выключения, так как вы обязательно создадите резервную копию почтового сервера или вашего почтового ящика. Вместо этого запишите эти случаи в файл и запланируйте задание cron, чтобы найти эти файлы error.log и отправьте их по почте администраторам.
источник
PHP имеет ловимые фатальные ошибки. Они определены как E_RECOVERABLE_ERROR. Руководство по PHP описывает E_RECOVERABLE_ERROR как:
Вы можете «поймать» эти «фатальные» ошибки с помощью set_error_handler () и проверяя E_RECOVERABLE_ERROR. Я считаю полезным генерировать исключение при обнаружении этой ошибки, тогда вы можете использовать try / catch.
Этот вопрос и ответ дают полезный пример: как я могу поймать «поддающуюся фатальной ошибке» подсказку типа PHP?
Ошибки E_ERROR, однако, могут быть обработаны, но не могут быть восстановлены, поскольку движок находится в нестабильном состоянии.
источник
Вот только хороший трюк, чтобы получить текущий метод error_handler =)
Также хочу отметить, что если вы позвоните
PHP перестает отображать ошибку. В противном случае текст ошибки будет отправлен клиенту до вашего обработчика ошибок.
источник
Поскольку большинство ответов здесь неоправданно многословны, вот моя не уродливая версия ответа с наибольшим количеством голосов:
источник
На самом деле, нет. Так называются фатальные ошибки, потому что они фатальны. Вы не можете оправиться от них.
источник
Я разработал эту функцию, чтобы сделать возможным «песочницу» кода, который может привести к фатальной ошибке. Поскольку исключения, генерируемые из замыкания
register_shutdown_function
, не передаются из стека вызовов до фатальной ошибки, я вынужден выйти после этой функции, чтобы обеспечить единообразный способ ее использования.источник
Существуют определенные обстоятельства, в которых должны быть обнаружены даже фатальные ошибки (вам может понадобиться сделать некоторую очистку, прежде чем грациозно выйти и не просто умереть ...).
Я реализовал хук pre_system в моем CodeIgniter приложениях чтобы я мог получать фатальные ошибки по электронной почте, и это помогло мне найти ошибки, о которых не сообщалось (или о которых сообщалось после того, как они были исправлены, поскольку я уже знал о них :)).
Sendemail проверяет, не было ли уже сообщено об ошибке, чтобы не отправлять вам спам с известными ошибками несколько раз.
источник