PHP: Обработка ошибок
Автор: | Артемьев Сергей Игоревич |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
В предыдущем уроке мы рассмотрели основы обработки исключений и различия между исключениями и ошибками. В этом уроке бы изучим опрядок обработки ошибок.
Ошибки в PHP можно разделить пользовательские и системные. К сожалению, перехватить системные ошибки стандартными средствами невозможно и единственный способ борьбы с ними - грамотное написание и отладка кода. Единственное, что можно (и нужно) сделать - запретить вывод в браузер любых сообщений об ошибках. Делается это при помощи функции error_reporting(). динственный параметр этой функции определяет какие ошибки разрешено выводить в браузер.
<?php // функцию лучше всего вызывать // в самом начале, до выполнения // других выражений error_reporing(E_ALL ^ E_NOTICE); // код скрипта ?>
Параметр функции может быть комбинацией следующих констант
Константа | Описание |
---|---|
E_ERROR | Критические ошибки, прерывающие выполнение скрипта (например, ошибка выделения памяти) |
E_WARNING | Предупреждения |
E_PARSE | Синтаксические ошибки исходного кода |
E_NOTICE | Замечания |
E_CORE_ERROR | Критические ошибки, возникающие на этапе запуска исполнения скрипта |
E_CORE_WARNING | Предупреждения, возникающие на этапе запуска |
E_COMPILE_ERROR | Ошибки компиляции |
E_COMPILE_WARNING | Предупреждения компиляции |
E_USER_ERROR | Пользовательские ошибки, созданные с помощью функции trigger_error() |
E_USER_WARNING | Пользовательские предупреждения, созданные с помощью функции trigger_error() |
E_USER_NOTICE | Пользовательские замечания, созданные с помощью функции trigger_error() |
E_ALL | Все возможные ошибки, предупреждения и замечания |
E_STRICT | Замечания времени выполнения |
E_RECOVERABLE_ERROR | Критические ошибки, допускающие дальнейшее исполнение кода. |
Например:
<?php // отображать всё error_reporting(E_ALL); // отображать всё, кроме замечаний error_reporting(E_ALL ^ E_NOTICE); // отображать только замечания и предупреждения error_reporting(E_NOTICE | E_WARNING); // не отображать ничего error_reporting(0); ?>
Иногда возникают случаи, когда надо запретить вывод ошибок не для всего скрипта, а лишь для его части. В этом случае необходимо пользоваться оператором подавления ошибок "@" (собака). Будучи поставлен перед выражением, этот оператор запрещает вывод на зкран всех сообщений, предупреждений или замечаний, генерируемых выражением. Например:
<?php $mailed = @mail('', '', ''); // если письмо не будет отправлено // но функция просто вернёт false, // не отображая никаких ошибок if(!$mailed) trigger_error('Ошибка отправки письма'); ?>
Пользовательские ошибки могут быть без проблем перехвачены и обработаны, причем обработка ошибок построена таким образом, что может выполняться без завершения основного скрипта.
Для генерации ошибки служит функция trigger_error(), которой передаётся два параметра - тип ошибки и собственно её текст. Тип ошибки определяется стандартными константами, рассмотренными выше.
Например:
<?php if(!isset($user_name) || trim($user_name) == '') trigger_error(E_USER_ERROR, 'Имя пользователя не указано'); if(!isset($user_passwd) || trim($user_passwd) == '') trigger_error(E_USER_ERROR, 'Пароль пользователя не указан'); ?>
Вызов функции trigger_error не приводит к аварийному завершению скрипта, а значит весь последующий код будет нормально исполняться. Если же прервать выполнение всё-таки необходимо, то программист должен сделать это "вручную", используя средства языка.
Как и для исключений, для ошибок можно установить собственный обработчик. Делается это при помощи функции set_error_handler(), которой передаётся имя функции-обработчика и список типов ошибок, для которых эта функция вызывается. Функция имеет четыре параметра: номер ошибки, текст ошибки, имя файла и номер строки, где ошибка произошла. Например:
<?php function specialHandler($errno, $errstr, $errfile, $errline) { switch ($errno) { case E_USER_ERROR: echo "Критическая ошибка: <br />\n" . "Номер: $errno <br />\n" . "Текст: $errstr <br />\n" . "Файл: $errfie <br />\n" . "Строка: $errline <br />\n"; exit(1); break; case E_USER_WARNING: echo "Предупреждение: [$errno] $errstr<br />\n"; break; case E_USER_NOTICE: echo "Замечание: [$errno] $errstr<br />\n"; break; default: echo "Неизвестная ошибка: [$errno] $errstr<br />\n"; break; } return true; } // указываем, что нам необходимо // проверять все возникающие ошибки set_error_handler('specialHandler', E_ALL); ?>
Если функция обработки ошибки возвращает true, то внутренний обработчик PHP не вызывается, а если false - то после выхода из пользовательской процедуры ошибка будут передана в стандартный внутренний обработчик. Это позволяет программисту реагировать только на часть возникающих ошибок, отдавая остальное старндартным обработчикам PHP.
Восстановить предыдущий обработчик можно, вызвав функцию restore_error_handler():
<?php set_error_handler('myFunction'); // // код // restore_error_handler(); ?>
Таким способом можно включать и выключать обработчики ошибок по мере необходимости. Но злоупотреблять такими операциями не стоит - слишком высока вероятность запутаться и перепутать обработчики. В большинстве случаев достаточно одного, но хорошо написанного обработчика, который пишет ошибки в лог-файл или базу данных, пересылает их на email администратора и делает другие полезные операции.
Обработка ошибок - один из важнейших элементов написания скриптов. Некачественно написанный срипт может стать не только головной болью веб-мастера или администратора сайта. "Бажный" (от слова "баг" - ошибка) скрипт представляет серьёзную угрозу безопасности. В руках умелого взломщика текст ошибки превращается в отмычку, открывающую доступ ко всему содержимому сайта, а может быть и сервера.