09
января
2008

Обработка сообщений об ошибках PHP

В заметке «Работа над ошибками» я уже упоминал о том, насколько неуместно на страницах сайта могут выглядеть сообщения об ошибках, выдаваемые интерпретатором PHP. Многие разработчики зачастую не уделяют должного внимания тому, чтобы избавить посетителей сайтов от необходимости лицезреть подобный мусор. Вероятно, самой массовой на то причиной (после лени, конечно) является вера в идеальность алгоритмов и абсолютную непотопляемость серверов БД. Тем не менее, одним из показателей грамотной реализации и внедрения системы является контролируемость вывода всех служебных сообщений интерпретатора.

Самый простой способ для этого — использовать функцию error_reporting() (или параметр конфигурационного файла PHP с аналогичным названием). С ее помощью можно, например, полностью отключить вывод ошибок в production версии скрипта, оставив их видимыми только для разработчика. Но это не самый оптимальный подход, т.к. он лишает возможности отслеживать исключительные ситуации в работе «боевой» версии.

Наиболее грамотное решение — перенаправлять все сообщения об ошибках в лог. Сделать это можно множеством способов. Один из них — тривиальный, с помощью set_error_handler() и других стандартных функций для обработки ошибок. Другой — через конфигурационные файлы Apache и PHP. На последнем я бы хотел остановиться более подробно.

Этот способ хорошо подходит в тех случаях, когда речь идет об установке чужих скриптов или есть иная причина, чтобы лишний раз не лезть в код. Способ основан на том факте, что вывод ошибок интерпретатором PHP управляем не только через функции, но и из конфигурационного файла. В свою очередь, параметры php.ini можно переопределять через локальные конфигурационные файлы Apache .htaccess. Таким образом, на одном сервере можно довольно удобно задавать различные настройки для разных директорий и установленных в них скриптов. При этом глобальные настройки останутся незатронутыми, что особенно акуально на shared хостингах, где доступа к ним просто нет.

Содержимое .htaccess:

php_flag display_startup_errors off
php_flag display_errors off
php_flag log_errors on
php_value error_log /home/motoko/logs/errors.log

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

[09-Jan-2008 15:11:57] PHP Parse error:  syntax error, 
unexpected '=' in /home/motoko/public_html/test_log/index.php on line 3
[09-Jan-2008 15:11:59] PHP Parse error:  syntax error, 
unexpected '=' in /home/motoko/public_html/test_log/index.php on line 3
…

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

Ссылки по теме

Комментарии к заметке «Обработка сообщений об ошибках PHP»

# Артём Курапов: (9 января, 2008 @ 23:08)

Не забудьте про фатальные ошибки. Их можно ловить при помощи ob_start(“ob_gzhandler”); Кроме переполнения памяти. Об этом Дмитрий Котеров писал недавно.

# admin: (11 января, 2008 @ 01:10)

Артём Курапов: Спасибо за дополнение. Не поделитесь линком на статью Котерова? Что-то не нашел я этой темы у него на dklab.ru.

# Kord: (14 января, 2008 @ 02:45)

Спасибо! Вы очень помогли! И не только мне!

# admin: (14 января, 2008 @ 13:20)

Kord: Приятно слышать.

# Олег Лобач: (15 января, 2008 @ 14:14)

Отвечу за Артёма: “Про перехват и обработку фатальных ошибок (Fatal Error) в PHP” (http://dklab.ru/chicken/nablas/45.html)

# admin: (15 января, 2008 @ 14:35)

Олег Лобач: Спасибо за ссылку.

# black zorro: (20 января, 2008 @ 23:39)

Можно перехватывать все что угодно, в том числе и сбои с памятью, если делать так. Перезапрос через curl собственно страницы выполняющей обработку, а потом анализировать что было возвращено.

$content = всяэтадребеденьс_curlполучить (‘stranica.php?a=1&b=2′); if (strpos ($content, ‘ERROR’)) die (‘КАПЕЦ’);

die ($content);

Написать комментарий

Можно использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> .