Иногда ваше приложение не запускается должным образом, что приводит к ошибкам. Есть ряд причин, которые могут вызвать ошибки, например:
- Веб-серверу может не хватить места на диске;
- Пользователь мог ввести недопустимое значение в поле формы;
- Файл или запись базы данных, к которой вы пытались получить доступ, возможно, не существует;
- Приложение может не иметь разрешения на запись в файл на диске;
- Служба, к которой приложение должно получить доступ, может быть временно недоступна.
Эти типы ошибок известны как ошибки времени выполнения, потому что они возникают во время выполнения скрипта. Они отличаются от синтаксических ошибок, которые необходимо исправлять перед запуском скриптов.
Профессиональное приложение должно иметь возможность изящно обрабатывать такие ошибки времени выполнения. Обычно это означает более четкое и точное информирование пользователя о проблеме.
Понимание уровней ошибок
Обычно, когда возникает проблема, препятствующая правильной работе скрипта, механизм PHP выдает ошибку. Каждая ошибка представлена целым числом и соответствующей константой. В следующей таблице перечислены некоторые из распространенных уровней ошибок:
Название | Значение | Описание |
---|---|---|
E_ERROR |
1 |
Неустранимая ошибка времени выполнения от которой невозможно избавиться. Выполнение скрипта немедленно прекращается. |
E_WARNING |
2 |
Предупреждение во время выполнения. Она несущественна, и большинство ошибок попадают в эту категорию. Выполнение скрипта не останавливается. |
E_NOTICE |
8 |
Уведомление во время выполнения. Указывает, что скрипт обнаружил что-то, что могло быть ошибкой, хотя такая ситуация также может возникнуть при обычном запуске скрипта. |
E_USER_ERROR |
256 |
Сообщение о фатальной пользовательской ошибке. Она похожа на E_ERROR , за исключением того, что она генерируется PHP-скриптом с использованием функции trigger_error() . |
E_USER_WARNING |
512 |
Предупреждающее сообщение, созданное пользователем без фатального исхода. Она похожа на E_WARNING , за исключением того, что она генерируется PHP-скриптом с использованием функции trigger_error() . |
E_USER_NOTICE |
1024 |
Сообщение с уведомлением, созданное пользователем. Она похожа на E_NOTICE за исключением того, что она генерируется PHP-скриптом с использованием функции trigger_error() . |
E_STRICT |
2048 |
Не совсем ошибка, но срабатывает всякий раз, когда PHP встречает код, который может привести к проблемам или несовместимости пересылки. |
E_ALL |
8191 |
Все ошибки и предупреждения, кроме E_STRICT до PHP 5.4.0. |
Дополнительные сведения об уровнях ошибок см. в справочнике по уровням ошибок PHP.
Механизм PHP вызывает ошибку всякий раз, когда он сталкивается с проблемой в вашем скрипте, но вы также можете инициировать ошибки самостоятельно, чтобы генерировать более удобные сообщения об ошибках. Таким образом вы можете сделать свое приложение более сложным. В следующем разделе описаны некоторые из распространенных методов, используемых для обработки ошибок в PHP:
Базовая обработка ошибок с помощью функции die()
Рассмотрим следующий пример, в котором просто попытаемся открыть текстовый файл только для чтения.
<?php
// Пробуем открыть несуществующий файл
$file = fopen("sample.txt", "r"); // Выводит: Warning: fopen(sample.txt) [function.fopen]: failed to open stream: No such file or directory in C:\wamp\www\project\test.php on line 2
?>
Если мы выполним несколько простых шагов, мы сможем предотвратить получение пользователями такого сообщения об ошибке.
<?php
if(file_exists("sample.txt")){
$file = fopen("sample.txt", "r");
} else{
die("Error: The file you are trying to access doesn't exist.");
}
?>
Как вы можете видеть, реализовав простую проверку, существует ли файл перед попыткой доступа к нему, мы можем сгенерировать сообщение об ошибке, которое будет более понятным для пользователя.
Используемая выше функция die()
просто отображает пользовательское сообщение об ошибке и завершает текущий скрипт, если файл sample.txt
не найден.
Создание собственного обработчика ошибок
Вы можете создать свою собственную функцию обработчика ошибок, чтобы справляться с ошибкой времени выполнения, генерируемой механизмом PHP. Пользовательский обработчик ошибок обеспечивает большую гибкость и лучший контроль над ошибками; он может проверять ошибку и решать, что с ней делать — отображать сообщение пользователю, регистрировать ошибку в файле или базе данных или отправлять по электронной почте, попытаться исправить проблему и продолжить, выйти из выполнения скрипта или вообще игнорировать ошибку.
Функция пользовательского обработчика ошибок должна иметь возможность обрабатывать как минимум два параметра (errno и errstr), однако она может дополнительно принимать три дополнительных параметра (errfile, errline и errcontext), как описано ниже:
Параметр | Описание |
---|---|
Обязательно — следующие параметры обязательны | |
errno. | Задает уровень ошибки в виде целого числа. Это соответствует соответствующей константе уровня ошибки (E_ERROR , E_WARNING и т. д.). |
errstr. | Задает сообщение об ошибке в виде строки. |
Опционально — следующие параметры являются необязательными | |
errfile. | Задает имя файла скрипта, в котором произошла ошибка. |
errline. | Задает номер строки, в которой произошла ошибка. |
errcontext. | Задает массив, содержащий все переменные и их значения, которые существовали на момент возникновения ошибки. Полезно для отладки. |
Вот пример простой пользовательской функции обработки ошибок. Этот обработчик customError()
запускается всякий раз, когда возникает ошибка, какой бы тривиальной она ни была. Затем он выводит сведения об ошибке в браузер и останавливает выполнение скрипта.
<?php
// Функция обработчика ошибок
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
?>
Вам нужно указать PHP, чтобы он использовал вашу пользовательскую функцию обработчика ошибок — просто вызовите встроенную функцию set_error_handler()
, передав имя функции.
<?php
// Функция обработчика ошибок
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
// Устанавливаем обработчик ошибок
set_error_handler("customError");
// Вызываем ошибку
echo($test);
?>
Регистрация ошибок
Журнал сообщений об ошибках в текстовом файле
Вы также можете записать подробную информацию об ошибке в файл журнала, например:
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
$message = date("Y-m-d H:i:s - ");
$message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
$message .= "Variables:" . print_r($errcontext, true) . "\r\n";
error_log($message, 3, "logs/app_errors.log");
die("There was a problem, please try again.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>
Отправка сообщений об ошибках по электронной почте
Вы также можете отправить электронное письмо с подробностями об ошибке, используя ту же функцию error_log()
.
<?php
function calcDivision($dividend, $divisor){
if ($divisor == 0){
trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
$message = date("Y-m-d H:i:s - ");
$message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
$message .= "Variables:" . print_r($errcontext, true) . "\r\n";
error_log($message, 1, "webmaster@example.com");
die("There was a problem, please try again. Error report submitted to webmaster.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>
Вызов ошибок
Хотя движок PHP выдает ошибку всякий раз, когда он сталкивается с проблемой в вашем скрипте, вы также можете вызвать ошибки самостоятельно. Это может помочь сделать ваше приложение более надежным, поскольку оно может выявлять потенциальные проблемы до того, как они перерастут в серьезные ошибки.
Чтобы вызвать ошибку в скрипте, вызовите функцию trigger_error()
, передав сообщение об ошибке, которое вы хотите сгенерировать:
trigger_error("There was a problem.");
Рассмотрим следующую функцию, которая вычисляет деление двух чисел.
<?php
function calcDivision($dividend, $divisor){
return($dividend / $divisor);
}
// Вызываем функцию
echo calcDivision(10, 0); // Выводит: Warning: Division by zero in C:\wamp\www\project\test.php on line 3
?>
Это сообщение выглядит не очень информативным. Рассмотрим следующий пример, в котором для генерации ошибки используется функция trigger_error()
.
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("Делитель не может быть нулевым", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
// Вызываем функцию
echo calcDivision(10, 0); // Выводит: Warning: Делитель не может быть нулевым C:\wamp\www\project\error.php on line 4
?>
Как видите, сообщение об ошибке, созданное во втором примере, более четко объясняет проблему по сравнению с предыдущим.