PHP Exception Handling
Исключения используются для изменения нормального потока сценария при возникновении указанной ошибки.
Что такое исключение
С PHP 5 появился новый объектно-ориентированный способ борьбы с ошибками.
Обработка исключений используется для изменения нормального потока выполнения кода, если возникает указанное условие ошибки (исключительная). Это условие называется исключением.
Это обычно происходит при срабатывании исключения:
- Текущее состояние кода сохраняется
- Выполнение кода переключится на предопределенную (настраиваемую) функцию обработчика исключений
- В зависимости от ситуации обработчик может затем возобновить выполнение из сохраненного состояния кода, завершить выполнение сценария или продолжить сценарий из другого места в коде
Мы будем показывать различные методы обработки ошибок:
- Основное использование исключений
- Создание пользовательского обработчика исключений
- Несколько исключений
- Повторное создание исключения
- Установка обработчика исключений верхнего уровня
Примечание: Исключения должны использоваться только с условиями ошибки и не должны использоваться для перехода в другое место кода в указанной точке.
Основное использование исключений
При возникновении исключения код, следующий за ним, не будет выполнен, и PHP попытается найти соответствующий блок catch.
Если исключение не перехвачено, Неустранимая ошибка будет выдана с сообщением "неперехваченное исключение".
Давайте попробуем бросить исключение, не ловя его:
<?php
//create function with an exception
function checkNum($number) {
if($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception
checkNum(2);
?>
Приведенный выше код будет получать ошибку, как это:
Фатальная ошибка: неперехваченное исключение ' Exception '
с сообщением ' значение должно быть 1 или ниже ' в к:\вебфолдер\тест.ФП: 6
Трассировка стека: #0 к:\вебфолдер\тест.ФП (12):
чеккнум (28) #1 {Main} брошен в к:\вебфолдер\тест.ФП на линии 6
Попробуй, брось и Поймай
Чтобы избежать ошибки из приведенного выше примера, нам нужно создать правильный код для обработки исключения.
Правильный код исключения должен включать:
try
- Функция, использующая исключение, должна находиться в блоке "try". Если исключение не запускается, код продолжит работу в обычном режиме. Однако при срабатывании исключения вызывается исключение ""throw
- Вот как вы запускаете исключение. Каждый "бросок" должен иметь по крайней мере один "улов"catch
- Блок "Catch" извлекает исключение и создает объект, содержащий сведения об исключении
Позволяет попытаться вызвать исключение с допустимым кодом:
<?php
//create function with an exception
function checkNum($number) {
if($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception in a "try" block
try {
checkNum(2);
//If the exception is thrown, this text will not be shown
echo 'If you see this, the number is 1 or below';
}
//catch exception
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
?>
Приведенный выше код будет получать ошибку, как это:
Сообщение: значение должно быть 1 или ниже
Пример объяснил:
Приведенный выше код вызывает исключение и перехватывает его:
- Создается функция чеккнум (). Он проверяет, если число больше 1. Если это так, возникает исключение
- Функция чеккнум () вызывается в блоке try
- Исключение в функции чеккнум () вызывается
- Блок "Catch" извлекает исключение и создает объект ($e), содержащий сведения об исключении
- Сообщение об ошибке из исключения повторяется путем вызова $e-> сообщение () из объекта Exception
Однако одним из способов обойти правило "каждый бросок должен иметь catch" является установка обработчика исключений верхнего уровня для обработки ошибок, проскальзывания.
Создание пользовательского класса исключений
Для создания пользовательского обработчика исключений необходимо создать специальный класс с функциями, которые могут быть вызваны при возникновении исключения в PHP. Класс должен быть расширением класса Exception.
Пользовательский класс исключений наследует свойства из класса исключений PHP, и в него можно добавлять пользовательские функции.
Позволяет создать класс исключений:
<?php
class customException extends Exception {
public function errorMessage() {
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "[email protected]";
try {
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new customException($email);
}
}
catch (customException $e) {
//display custom message
echo $e->errorMessage();
}
?>
Новый класс является копией старого класса Exception с добавлением функции ErrorMessage (). Так как это копия старого класса, и он наследует свойства и методы из старого класса, мы можем использовать методы класса Exception, такие как: line () и файл () и Message ().
Пример объяснил:
Приведенный выше код создает исключение и перехватывает его с помощью пользовательского класса исключений:
- Класс кустомексцептион () создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства из старого класса исключений
- Создается функция ErrorMessage (). Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недопустимым
- Переменная $email устанавливается в строку, которая не является допустимым адресом электронной почты
- Блок "try" выполняется и создается исключение, поскольку адрес электронной почты является недопустимым
- Блок catch перехватывает исключение и выводит сообщение об ошибке
Несколько исключений
Сценарий может использовать несколько исключений для проверки нескольких условий.
Можно использовать несколько if.. else блокирует, переключатель или вложение нескольких исключений. Эти исключения могут использовать различные классы исключений и возвращать различные сообщения об ошибках:
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "[email protected]";
try {
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new customException($email);
}
//check for "example" in mail address
if(strpos($email, "example") !== FALSE) {
throw new Exception("$email is an example e-mail");
}
}
catch (customException $e) {
echo $e->errorMessage();
}
catch(Exception $e) {
echo $e->getMessage();
}
?>
Пример объяснил:
Приведенный выше код проверяет два условия и создает исключение, если какое-либо из условий не выполнено:
- Класс кустомексцептион () создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства из старого класса исключений
- Создается функция ErrorMessage (). Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недопустимым
- Переменная $email устанавливается в строку, которая является допустимым адресом электронной почты, но содержит строку "example"
- Блок "try" выполняется и исключение не выбрасывается при первом условии
- Второе условие вызывает исключение, так как сообщение электронной почты содержит строку "example"
- Блок "Catch" перехватывает исключение и отображает правильное сообщение об ошибке
Если исключение возникает из класса кустомексцептион и не было кустомексцептион catch, только базовый перехват исключений, исключение будет обрабатываться там.
Повторное создание исключений
Иногда, когда возникает исключение, вы можете обработать его иначе, чем стандартный способ. Можно выдать исключение во второй раз в блоке "Catch".
Сценарий должен скрывать системные ошибки от пользователей. Системные ошибки могут быть важны для кодера, но не представляют интереса для пользователя. Чтобы упростить задачу пользователя, можно повторно вызвать исключение с удобным сообщением:
<?php
class customException extends Exception {
public function errorMessage() {
//error message
$errorMsg = $this->getMessage().' is not a valid E-Mail address.';
return $errorMsg;
}
}
$email = "[email protected]";
try {
try {
//check for "example" in mail address
if(strpos($email, "example") !== FALSE) {
//throw exception if email is not valid
throw new Exception($email);
}
}
catch(Exception $e) {
//re-throw exception
throw new customException($email);
}
}
catch (customException $e) {
//display custom message
echo $e->errorMessage();
}
?>
Пример объяснил:
Приведенный выше код проверяет, если адрес электронной почты содержит строку "example" в нем, если он делает, исключение повторно выбрасывается:
- Класс кустомексцептион () создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства из старого класса исключений
- Создается функция ErrorMessage (). Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недопустимым
- Переменная $email устанавливается в строку, которая является допустимым адресом электронной почты, но содержит строку "example"
- Блок «try» содержит еще один блок «try», чтобы сделать возможным повторное выбросить исключение
- Исключение запускается, поскольку сообщение содержит строку "example"
- Блок "Catch" ловит исключение и повторно бросает "кустомексцептион"
- "кустомексцептион" пойман и выводит сообщение об ошибке
Если исключение не перехвачено в текущем блоке try, он будет искать блок catch на "более высоких уровнях".
Установка обработчика исключений верхнего уровня
set_exception_handler()
функция задает определяемую пользователем функцию для обработки всех неперехваченных исключений:
<?php
function myException($exception)
{
echo "<b>Exception:</b> " . $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>
Результат приведенного выше кода должен быть примерно таким:
Exception: Uncaught Exception occurred
В вышеприведенном коде нет блока "Catch". Вместо этого запускается обработчик исключений верхнего уровня. Эта функция должна использоваться для перехвата неперехваченных исключений.
Правила для исключений
- Код может быть окружен в блоке try, чтобы помочь поймать потенциальных исключений
- Каждый блок try или "Throw" должен иметь по крайней мере один соответствующий блок catch
- Для перехвата различных классов исключений можно использовать несколько блоков catch
- Исключения могут быть выброшены (или повторно сгенерированы) в блоке catch в блоке try
Простое правило: Если вы бросаете что-то, вы должны поймать его.