Home » Программирование » Короткие заметки » О порядке обработки ошибок в PHP

О порядке обработки ошибок в PHP

Включение вывода ошибок уровня Notice, Deprecated или Strict, может спровоцировать дополнительные сообщения уровня Warning, а то и приводить к фатальным ошибкам от некоторых PHP библиотек или компонентов. К таким компонентам относится, например, популярный SapiEmitter из ZendFramework, который проверяет отправку заголовков с помощью директивы headers_sent(). Это нужно иметь в виду, если в ходе отладки вы пытаетесь найти проблемное место, а дойти до него не можете из-за банального падения SapiEmittera в Fatal при слишком подробном выводе ошибок.
Итак, приступим к подробному рассмотрению проблемы.

Допустим, мы включили отображение всех ошибок:

E_ALL

И увидели на экране несколько Notice и Warning.

Включим подавление Notice, чтобы отфильтровать Warning

E_ALL & ~E_NOTICE

К своему удивлению мы зачастую можем обнаружить, что Warning-и исчезли вместе с Notice!
Если же включить фильтрацию Warning, но оставить отображение Notice, то, действительно, останутся только Notice:

E_ALL & ~E_WARNING

Куда деваются Warning-и при отключении Notice? Оказывается, если внимательно почитать содержимое Warning-ов, то можно обнаружить хрестоматийные ошибки типа headers already sent, указывающие на преждевременно отправленные заголовки. Так бывает, если на экран что-то выводится раньше, чем оно должно быть на самом деле. А бывает это очень часто вовсе не из-за небрежно написанного кода, а в результате вывода ошибок на экран — именно эти Notice (а также Deprecated и т.п.) портят заголовки своим преждевременным появлением.

Таким образом, отображение ошибок одного уровня может породить ошибки другого уровня.
Мораль: подавление предупреждений типа Notice скрывает множество предупреждений типа Warning и других.

Поэтому, для отлова всех возможных узких мест необходимо

  1. Включить отображение всех ошибок E_ALL с подавлением Notices. Мы получим список ошибок типа Warning, которые не будут зависеть от Notices.
  2. После избавления от Warning-ов на предыдущем шаге включаем отображение Notices и получаем ещё один набор Warning-ов, вызванных отображением Notices. Устраняем эти Warning-и за исключением, пожалуй, сообщений типа «headers already sent».
  3. Затем устраняем Notices, как наименее критичные предупреждения.

И ещё одна практическая рекомендация.

При работе с популярным сервером OpenServer я столкнулся со странными «предпочтениями» браузера Google Chrome при включении/отключении показа ошибок в коде PHP. А имено, браузер показывал ошибки через раз или вовсе отказывался это делать, если я пользовался стандартной директивой PHP error_reporting(…), тогда как аналогичная по функционалу директива ini_set(«error_reporting», …) в том же самом месте работала безотказно. Кроме того, браузеру было абсолютно наплевать на параметр display_error, значение которого ни на что не влияло.

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

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Do NOT follow this link or you will be banned from the site!