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 администратора и делает другие полезные операции.
Обработка ошибок - один из важнейших элементов написания скриптов. Некачественно написанный срипт может стать не только головной болью веб-мастера или администратора сайта. "Бажный" (от слова "баг" - ошибка) скрипт представляет серьёзную угрозу безопасности. В руках умелого взломщика текст ошибки превращается в отмычку, открывающую доступ ко всему содержимому сайта, а может быть и сервера.