PHP Обработка ошибок


В PHP обработка ошибок по умолчанию проста. Сообщение об ошибке отправляется в браузер и содержит имя файла, номер строки и сообщение с описанием ошибки.


Обработка ошибок в PHP

Обработка ошибок — важная часть при создании скриптов и веб-приложений. Если в вашем коде отсутствует код обнаружения ошибок, программа выглядит непрофессионально и открывает дверь для угроз безопасности.

В этом руководстве представлены некоторые из наиболее важных методов обнаружения ошибок в PHP.

Мы объясним вам различные методы обработки ошибок:

  • Простые конструкции "die()"
  • Пользовательские ошибки и триггеры ошибок
  • Отчеты об ошибках

Базовая обработка ошибок: использование функции die()

В первом примере показан простой скрипт, который открывает текстовый файл:

<?php
$file=fopen("welcome.txt","r");
?>

Если файл не существует, вы получите примерно такую ошибку:

Warning: fopen(welcome.txt) [function.fopen]: failed to open stream:
No such file or directory in /www/example/test/test.php on line 2

Чтобы пользователи не получали сообщение об ошибке, подобное приведенному выше, мы проверяем, существует ли файл, перед обращением к нему:

<?php
if(!file_exists("welcome.txt"))
{
    die("文件不存在");
}
else
{
    $file=fopen("welcome.txt","r");
}
?>

Теперь, если файл не существует, вы получите сообщение об ошибке, подобное этому:

File does not exist.

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

Однако простое завершение сценария не всегда является подходящим подходом. Давайте рассмотрим альтернативные функции PHP, используемые для обработки ошибок.


Создание собственного обработчика ошибок

Создание собственного обработчика ошибок очень просто. Мы просто создаём специальную функцию, которая может быть вызвана при возникновении ошибки в PHP.

Функция должна уметь обрабатывать как минимум два параметра (уровень ошибки и сообщение об ошибке), но может принимать до пяти параметров (необязательно: файл, номер строки и контекст ошибки):

Синтаксис

error_function(error_level,error_message,
error_file,error_line,error_context)
Параметр Описание
error_level Обязательный. Задаёт уровень сообщения об ошибке для пользовательской ошибки. Должен быть числом. См. таблицу ниже: Уровни сообщений об ошибках.
error_message Обязательный. Указывает сообщение об ошибке для определяемой пользователем ошибки.
error_file Необязательный. Указывает имя файла, в котором произошла ошибка.
error_line Необязательный. Задаёт номер строки, в которой произошла ошибка.
error_context Необязательный. Задаёт массив, содержащий все переменные и их значения, использовавшиеся в момент возникновения ошибки.

Уровни сообщений об ошибках

Эти уровни сообщений об ошибках — это различные типы ошибок, обрабатываемые пользовательским обработчиком ошибок:

Значение Константа Описание
2 E_WARNING Нефатальные ошибки времени выполнения. Не останавливают выполнение сценария.
8 E_NOTICE Уведомления времени выполнения. Возникают, когда сценарий обнаруживает возможную ошибку, но также могут возникать при нормальной работе сценария.
256 E_USER_ERROR Фатальные ошибки, сгенерированные пользователем. Они похожи на E_ERROR, устанавливаемые программистом с помощью функции PHP trigger_error().
512 E_USER_WARNING Нефатальные предупреждения, генерируемые пользователем. Они аналогичны E_WARNING, устанавливаемым программистом с помощью функции PHP trigger_error().
1024 E_USER_NOTICE Уведомления, генерируемые пользователем. Они аналогичны E_NOTICE, устанавливаемым программистом с помощью функции PHP trigger_error().
4096 E_RECOVERABLE_ERROR Перехватываемые фатальные ошибки. Похожи на E_ERROR, но могут быть перехвачены пользовательским обработчиком. (См. set_error_handler())
8191 E_ALL Все ошибки и предупреждения. (В PHP 5.4 E_STRICT вошёл в состав E_ALL.)

Теперь давайте создадим функцию, которая обрабатывает ошибки:

function customError($errno, $errstr)
{
    echo "<b>Error:</b> [$errno] $errstr<br>";
    echo "脚本结束";
    die();
}

Приведённый выше код — это простая функция обработки ошибок. При её срабатывании она принимает уровень ошибки и сообщение об ошибке. Затем она выводит уровень ошибки и сообщение и завершает скрипт.

Теперь, когда мы создали функцию обработки ошибок, нам нужно определить, когда следует вызывать эту функцию.


Настройка обработчика ошибок

Стандартный обработчик ошибок PHP — это встроенный обработчик ошибок. Мы собираемся сделать приведённую выше функцию стандартным обработчиком ошибок во время выполнения скрипта.

Обработчик ошибок можно изменить так, чтобы он применялся только к определённым ошибкам, позволяя скрипту обрабатывать разные ошибки разными способами. Однако в этом примере мы собираемся использовать наш пользовательский обработчик ошибок для всех ошибок:

set_error_handler("customError");

Поскольку мы хотим, чтобы наша пользовательская функция обрабатывала все ошибки, set_error_handler() требует только один параметр. Можно добавить второй параметр, чтобы указать уровень ошибки.

Пример

Проверьте этот обработчик ошибок, попытавшись вывести переменную, которая не существует:

<?php
// 错误处理函数
function customError($errno, $errstr)
{
    echo "<b>Error:</b> [$errno] $errstr";
}

// 设置错误处理函数
set_error_handler("customError");

// 触发错误
echo($test);
?>

Вывод приведённого выше кода показан ниже:

Error: [8] Undefined variable: test


Генерация ошибок

В местах скрипта, где вводятся пользовательские данные, полезно генерировать ошибки, когда ввод пользователя недопустим. В PHP эта задача выполняется функцией trigger_error().

Пример

В этом примере возникает ошибка, если переменная "test" больше "1":

<?php
$test=2;
if ($test>1)
{
    trigger_error("变量值必须小于等于 1");
}
?>

Вывод приведённого выше кода показан ниже:

Notice: 变量值必须小于等于 1
in /www/test/example.php on line 5

Вы можете генерировать ошибки в любом месте вашего скрипта. Добавив второй параметр, вы можете указать тип вызываемой ошибки.

Возможные типы ошибок:

  • E_USER_ERROR — фатальная ошибка времени выполнения, сгенерированная пользователем. Восстановление после ошибки невозможно. Выполнение скрипта прерывается.
  • E_USER_WARNING — нефатальное предупреждение времени выполнения, сгенерированное пользователем. Выполнение скрипта не прерывается.
  • E_USER_NOTICE — значение по умолчанию. Уведомление времени выполнения, сгенерированное пользователем. Возникает, когда скрипт обнаруживает возможную ошибку, но также может возникать при нормальной работе скрипта.

Пример

В этом примере возникает ошибка E_USER_WARNING, если переменная "test" больше "1". Если возникает E_USER_WARNING, мы используем наш собственный обработчик ошибок и завершим скрипт:

<?php
// 错误处理函数
function customError($errno, $errstr)
{
    echo "<b>Error:</b> [$errno] $errstr<br>";
    echo "脚本结束";
    die();
}

// 设置错误处理函数
set_error_handler("customError",E_USER_WARNING);

// 触发错误
$test=2;
if ($test>1)
{
    trigger_error("变量值必须小于等于 1",E_USER_WARNING);
}
?>

Вывод приведённого выше кода показан ниже:

Error: [512] 变量值必须小于等于 1
脚本结束

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


Логирование ошибок

По умолчанию, в зависимости от конфигурации error_log в php.ini, PHP отправляет журналы ошибок в систему журналирования сервера или в файл. С помощью функции error_log() вы можете отправлять журналы ошибок в указанный файл или удалённое назначение.

Отправка сообщений об ошибках себе по электронной почте — хороший способ получать уведомления о конкретных ошибках.

Отправка сообщений об ошибках по электронной почте

В следующем примере, если возникает определенная ошибка, мы отправим электронное письмо с сообщением об ошибке и завершим скрипт:

<?php
// 错误处理函数
function customError($errno, $errstr)
{
    echo "<b>Error:</b> [$errno] $errstr<br>";
    echo "已通知网站管理员";
    error_log("Error: [$errno] $errstr",1,
    "[email protected]","From: [email protected]");
}

// 设置错误处理函数
set_error_handler("customError",E_USER_WARNING);

// 触发错误
$test=2;
if ($test>1)
{
    trigger_error("变量值必须小于等于 1",E_USER_WARNING);
}
?>

Вывод приведённого выше кода показан ниже:

Error: [512] 变量值必须小于等于 1
已通知网站管理员

Электронное письмо, полученное от приведенного выше кода, показано ниже:

Error: [512] 变量值必须小于等于 1

Этот метод подходит не для всех ошибок. Обычные ошибки следует регистрировать на сервере с помощью стандартной системы журналирования PHP.

Другие расширения