English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP Основной Урок

PHP Уровеньный Урок

PHP & MySQL

PHP Референс Мануал

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

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

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

Иногда ваше приложение может не работать корректно,从而导致 ошибки. Есть несколько причин, которые могут привести к ошибкам, например:

  • Веб-сервер может не иметь достаточного места на диске

  • Пользователь может ввести недопустимое значение в поле формы

  • Файл или запись базы данных, к которому вы пытаетесь получить доступ, может не существовать

  • Приложение может не иметь прав на запись файлов на диск

  • Сервисы, к которым приложение должно получить доступ, могут быть временно недоступны

Эти типы ошибок называются ошибками времени выполнения, потому что они происходят во время выполнения скрипта. Они отличаются от синтаксических ошибок, которые необходимо исправить до выполнения скрипта.

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

Понимание уровней ошибок

Обычно, когда скрипт сталкивается с проблемами, которые могут привести к его неработоспособности, движок PHP активирует ошибки. Каждая ошибка представлена целым числом и соответствующей константой. В таблице приведены некоторые распространенные уровни ошибок:

Уровень ошибкиЗначениеОписание
E_ERROR1

Смертельные ошибки времени выполнения, которые невозможно восстановить. Выполнение скрипта немедленно останавливается.

E_WARNING2

Предупреждения о времени выполнения. Они не смертельные, большинство ошибок относится к этой категории. Выполнение скрипта не останавливается.

E_NOTICE8

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

E_USER_ERROR256

Катастрофические ошибки, созданные пользователем. Это похоже на E_ERROR, но они генерируются PHP-скриптом с помощью функции trigger_error(), а не PHP-движком.

E_USER_WARNING512Ненефатальные уведомления, созданные пользователем. Это похоже на E_WARNING, но они генерируются PHP-скриптом с помощью функции trigger_error(), а не PHP-движком.
E_USER_NOTICE1024

Уведомления, созданные пользователем. Это похоже на E_NOTICE, но они генерируются PHP-скриптом с помощью функции trigger_error(), а не PHP-движком.

E_STRICT2048

Точнее говоря, это не ошибка, но PHP активирует её при встрече с кодом, который может привести к проблемам или несовместимости с будущими версиями.

E_ALL8191

Все ошибки и предупреждения, за исключением E_STRICT до PHP 5.4.0.

Для получения информации о более высоких уровнях ошибок, пожалуйста, обратитесь кУровни ошибок PHPссылка.

Каждый раз, когда PHP-скрипт встречает проблему, движок PHP инициирует ошибку, но вы также можете инициировать ошибку самостоятельно, чтобы генерировать более дружественные пользователю сообщения об ошибках. Таким образом, вы можете сделать приложение более сложным. В следующей части описаны一些常用的 методы обработки ошибок PHP:

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

Рассмотрим следующий пример, который пытается открыть текстовый файл в режиме только для чтения.

<?php
// Попытка открыть не существующий файл
$file = fopen("sample.txt", "r");
?>

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

Предупреждение: fopen(sample.txt) [функция.fopen]: не удалось открыть поток: нет такой файл или каталог в C:\wamp\www\project\test.php на строке 2

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

<?php
if(file_exists("sample.txt")){
    $file = fopen("sample.txt", "r");
} else {
    die("Ошибка: Файл, к которому вы пытаетесь получить доступ, не существует.");
}
?>

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

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

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

Если файл “sample.txt” не найден, то функция die(), используемая выше, показывает только пользовательское сообщение об ошибке и завершает текущий скрипт.

Создание пользовательской функции обработки ошибок

Вы можете создать свою функцию обработки ошибок для обработки временных ошибок, генерируемых движком 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(): Делимое не может быть нулём", 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 .= "Ошибка: [" . $errno . "], ". ". $errstr в $errfile на строке $errline;
    $message .= "Переменные:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 3, "logs/app_errors.log");
    die("Произошла ошибка, пожалуйста, повторите попытку.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "Это никогда не будет напечатано.";
?>

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

Вы также можете использовать функцию error_log() для отправки электронной почты с деталями ошибки.

<?php
function calcDivision($dividend, $divisor) {
    if ($divisor == 0){
        trigger_error("calcDivision(): Делимое не может быть нулём", 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 .= "Ошибка: [" . $errno . "], ". ". $errstr в $errfile на строке $errline;
    $message .= "Переменные:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 1, "[email protected]");
    die("Проблема arose, пожалуйста, попробуйте еще раз. Ошибочный отчет был отправлен администратору сайта.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "Это никогда не будет напечатано.";
?>

Инициировать ошибку

Хотя PHP-движок генерирует ошибки при возникновении проблем в скрипте, вы также можете инициировать ошибки самостоятельно. Это может помочь сделать ваше приложение более мощным, так как оно может отметить потенциальные проблемы до того, как они станут серьезными ошибками.

Чтобы инициировать ошибку из скрипта, вызовите функцию trigger_error() и передайте ей сообщение об ошибке, которое нужно сгенерировать:

trigger_error("Проблема arose.");

Рассмотрим функцию для вычисления деления двух чисел.

<?php
function calcDivision($dividend, $divisor) {
    return($dividend / $divisor);
}
 
// Вызов функции
echo calcDivision(10, 0);
?>

Если передается нулевое значение в качестве параметра $divisor, то PHP-движок генерирует ошибку, подобную следующему содержимому:

Предупреждение: Деление на ноль в C:\wamp\www\project\test.php на строке 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);
?>

Теперь скрипт генерирует следующую ошибку сообщения:

Предупреждение: Делилитель не может быть нулём в C:\wamp\www\project\error.php на строке 4  	

Как вы видите, вторая примерная ошибка более ясно объясняет проблему по сравнению с предыдущим примером.