PHP5 Обработка исключений
Исключения используются для изменения нормального потока скрипта при возникновении указанной ошибки.
Что такое исключение?
В PHP5 появился новый объектно-ориентированный способ борьбы с ошибками.
Обработка исключений используется для изменения нормального потока выполнения кода,
если возникает указанное (исключительное) условие ошибки.
Это условие, называется исключение
Это то, что обычно происходит, когда срабатывает исключение:
- Текущее состояние кода сохраняется
- Выполнение кода переключится на предопределенную (пользовательскую) функцию, обработчик исключений
- В зависимости от ситуации обработчик может, возобновить выполнение из сохраненного состояния кода, завершить выполнение сценария или продолжить сценарий из другого расположения в коде
Мы покажем различные методы обработки ошибок:
- Основное использование исключений
- Создание пользовательского обработчика исключений
- Несколько исключений
- Повторное создание исключения
- Установка обработчика исключений верхнего уровня
Примечание: Исключения должны использоваться только с условиями ошибки и не должны использоваться для перехода на другое место в коде в указанной точке.
PHP Основное использование исключений
При возникновении исключения, следующий за ним код не будет выполнен и PHP будет пытаться найти соответствующий блок "Поймать".
Если исключение не перехватывается, фатальная ошибка будет выдаваться как сообщение "Необработанное исключение".
Попробуем выбросить исключение, не поймав его:
Пример
<?php
//создать функцию с помощью исключения
function checkNum($number) {
if($number>1) {
throw new Exception("Значение должно быть 1 или ниже");
}
return true;
}
//Вызов исключения
checkNum(2);
?>
Код выше получит ошибку, как эта:
Фатальная ошибка: Неперехваченное исключение 'Exception'
с сообщением 'Значение должно быть 1 или ниже' в C:\webfolder\test.php:6
Трассировка стека: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} заброшенный в C:\webfolder\test.php на линии 6
PHP Пробовать, забросить и вытащить
Чтобы избежать ошибки из приведенного выше примера, Вы должны создать код для обработки исключения.
Правильный код исключения должен включать:
- Пробовать - используется исключение в блоке
try
. Если исключение не срабатывает, код будет работать как обычно. Однако, если исключение срабатывает, исключение будетthrown
- Забросить - вызывает исключение. Каждый
throw
должен иметь хотя бы одинcatch
- Вытащить - Один блок
catch
получает исключение и создает объект, содержащий сведения об исключении
Давайте попробуем вызвать исключение с допустимым кодом:
Пример
<?php
//создать функцию с исключением
function checkNum($number) {
if($number>1) {
throw new Exception("Значение должно быть 1 или ниже");
}
return true;
}
//вызвать исключения в блоке "try"
try {
checkNum(2);
//Если исключение выбрасывается, этот текст не будет отображаться
echo 'Если Вы видите это, значение должно быть 1 или ниже';
}
//исключение catch
catch(Exception $e) {
echo 'Сообщение: ' .$e->getMessage();
}
?>
Код выше получит ошибку, как эта:
Сообщение: Если Вы видите это, значение должно быть 1 или ниже
Объяснение примера:
Приведенный выше код создает исключение и перехватывает его:
- Функция создает
checkNum()
. Она проверяет, если число больше, чем 1. Если это так, то исключениеthrow
- функция вызывается
checkNum()
в блокtry
- Исключение
checkNum()
в функции thrown - Блок
catch
получает исключение и создает объект$е
, содержащий сведения об исключении - Сообщение об ошибке из исключения повторяется вызовом
$e->getMessage()
из объекта исключение
Тем не менее, один из способов обойти "каждый throw
должен иметь catch
" поймать
установите обработчик исключений верхнего уровня для обработки ошибок, которые проходят.
PHP Создание пользовательского класса исключений
Для создания пользовательского обработчика исключений необходимо создать специальный класс функций, которые могут вызываться при возникновении исключения в PHP. Тот класс должен быть расширением класса исключений.
Пользовательский класс исключений наследует свойства от PHP класс исключений и в него можно добавлять пользовательские функции.
Позволяет создать класс исключения:
Пример
<?php
class customException extends Exception {
public function errorMessage() {
//сообщение об ошибке
$errorMsg = 'Ошибка на линии '.$this->getLine().' в '.$this->getFile()
.': <b>'.$this->getMessage().'</b> не является допустимым адресом электронной почты';
return $errorMsg;
}
}
$email = "someone@example...com";
try {
//проверить, если
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//исключение throw, если e-mail не является допустим
throw new customException($email);
}
}
catch (customException $e) {
//показать пользовательское сообщение
echo $e->errorMessage();
}
?>
Новый класс является копией старого класса исключений, с добавлением функции errorMessage()
.
Так как это копия старого класса и она наследует свойства и методы из старого класса,
мы можем использовать класс исключений метод вызова getline(), метод getfile() и метод getmessage().
Объяснение примера:
Приведенный выше код создает исключение и перехватывает его с помощью пользовательского класса исключений:
- Класс
customException()
создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства из старого класса исключений - Функция
errorMessage()
создана. Данная функция возвращает сообщение об ошибке, если адрес электронной почты является недействительным - Переменной
$email
присваивается строка, которая не является допустимым адресом электронной почты - Блок
try
выполняется и возникает исключение, так как адрес электронной почты является недопустимым - Блок
catch
вытаскивает исключение и отображает сообщение об ошибке
Несколько исключений
Сценарий может использовать несколько исключений для проверки нескольких условий.
Можно использовать несколько блоков if..else
,
switch
или вложенных несколько исключений.
Эти исключения могут использовать различные классы исключений и возвращать различные сообщения об ошибках:
Пример
<?php
class customException extends Exception
{
public function errorMessage()
{
//сообщение об ошибке
$errorMsg = 'Ошибка на линии '.$this->getLine().' в '.$this->getFile()
.': <b>'.$this->getMessage().'</b> не является допустимым адресом электронной почты';
return $errorMsg;
}
}
$email = "someone@example.com";
try {
//проверить, если
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//исключение throw, если e-mail не является допустим
throw new customException($email);
}
//проверить "example" в почтовом адресе
if(strpos($email, "example") !== FALSE) {
throw new Exception("$email является example e-mail");
}
}
catch (customException $e) {
echo $e->errorMessage();
}
catch(Exception $e) {
echo $e->getMessage();
}
?>
Объяснение примера:
Приведенный выше код проверяет два условия и создает исключение, если какое-либо из условий не выполняется:
- Класс
customException()
создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства из старого класса исключений - Создается функция
errorMessage()
). Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недействительным - Переменная
$email
устанавливается в строку, которая является допустимым адресом электронной почты, но содержит строку "example" - Блок
try
выполняется и исключение не возникает при первом условии - Второе условие вызывает исключение, так как сообщение электронной почты содержит строку "example"
- Блок
catch
вытаскивает исключение и отображает правильное сообщение об ошибке
Если исключение было из класса customException и не было customException поймано, только исключение catch, исключение будет сделано так.
PHP Повторное создание исключений
Иногда, когда возникает исключение, может потребоваться обработать его по-другому, чем стандартный способ. Можно забросить исключение во второй раз в блок "catch".
Сценарий должен скрывать системные ошибки от пользователей. Системные ошибки могут быть важны для кодера, но не представляют интереса для пользователя. Чтобы для пользователя задачу сделать проще, Вы можете повторно забросить исключение с удобным для пользователя сообщением:
Пример
<?php
class customException extends Exception {
public function errorMessage() {
//сообщение об ошибке
$errorMsg = $this->getMessage().' не является допустимым адресом электронной почты.';
return $errorMsg;
}
}
$email = "someone@example.com";
try {
try {
//проверить "example" в почтовом адресе
if(strpos($email, "example") !== FALSE) {
//исключение throw, если электронная почта не является допустимой
throw new Exception($email);
}
}
catch(Exception $e) {
//повторного исключение throw
throw new customException($email);
}
}
catch (customException $e) {
//показать пользовательское сообщение
echo $e->errorMessage();
}
?>
Объяснение примера:
Приведенный выше код проверяет, содержит ли адрес электронной почты строку "example", если содержит, исключение thrown создается повторно:
- Класс customException () создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства из старого класса исключений
- Создается функция errorMessage(). Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недействительным
- Переменная $email устанавливается в строку, которая является допустимым адресом электронной почты, но содержит строку "example"
- В блоке "try" содержится еще один блок "try", чтобы повторно сгенерировать исключение throw
- Исключение срабатывает с момента электронной почты, содержит строку "example"
- Блок "catch" перехватывает исключение и повторно забрасывает "customException"
- "customException" перехватил и отображает сообщение об ошибке
Если исключение не поймано в ее текущей блоке "try", он будет искать блок catch "более высокого уровня".
PHP Установка обработчика исключений верхнего уровня
Функция set_exception_handler() задает пользовательскую функцию для обработки всех необработанных исключений:
Пример
<?php
function myException($exception)
{
echo "<b>Исключение:</b> " . $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Произошло необработанное исключение');
?>
Выходные данные приведенного выше, код должны быть примерно такими:
Исключение: Произошло необработанное исключение
В коде выше нет блока "catch". Вместо этого сработал обработчик исключений верхнего уровня. Эта функция должна использоваться для отслеживания необработанных исключений.
Правила для исключений
- Код может быть окружен блоком try, чтобы помочь поймать потенциальные исключения
- Каждый блок try или "throw" должны иметь по крайней мере один соответствующий блок catch
- Для перехвата различных классов исключений можно использовать несколько блоков catch
- Исключения могут быть брошены (или повторно брошены) в блоке catch в блоке try
Простое правило: если Вы что-то бросаете, вы должны поймать его.