Исключения используются для изменения нормального потока скрипта, если происходит указанная ошибка.
Что такое исключение
С PHP 5 появился новый объектно-ориентированный способ борьбы с ошибками.
Обработка исключений используются для изменения нормального потока выполнения кода , если указанная ошибка (exceptional) в (exceptional) происходит состояние. Это состояние называется исключением.
Это то, что обычно происходит, когда исключение вызвано:
- Текущее состояние код сохраняется
- Выполнение кода переключится на предопределенную (custom) функцию обработчика исключений
- В зависимости от ситуации, обработчик может затем возобновить выполнение из сохраненного состояния кода, прекратить выполнение сценария или продолжить скрипт из другого места в коде
Мы покажем различные методы обработки ошибок:
- Основное использование Исключений
- Создание обработчика исключений
- Несколько исключений
- Повторно бросать исключение
- Установка обработчика исключений верхнего уровня
Note: Исключения должны быть использованы только с условиями ошибок, и не должны использоваться для перехода на другое место в коде в заданной точке.
Основы использования исключений
Когда возникает исключение, то код после него не будет выполняться, и PHP попытается найти соответствующий "catch" блок.
Если исключение не перехвачено, фатальная ошибка будет выдаваться с "Uncaught Exception" сообщения.
Попробуем бросить исключение, не поймав его:
<?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);
?>
Код выше получите ошибку, как это:
Fatal error : Uncaught exception 'Exception'
with message 'Value must be 1 or below' in C:\webfolder\test.php:6
Stack trace: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6
Попробуйте, бросать и ловить
Чтобы избежать ошибки из приведенного выше примера, нам нужно создать правильный код для обработки исключения.
Правильный код исключения должен включать в себя:
- Попробуйте - Функция , используя исключение должно быть в "try" блок. Если исключение не срабатывает, то код будет продолжаться в обычном режиме. Однако , если исключение вызывает, исключение "thrown"
- Бросок - Это как вызвать исключение. Каждый "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();
}
?>
Код выше получите ошибку, как это:
Message: Value must be 1 or below
Объяснение примера:
Код выше генерирует исключение, и ловит его:
- checkNum() функция создается. Он проверяет, является ли число больше 1. Если есть, исключение
- checkNum() функция вызывается в "try" блок
- Исключение в checkNum() функции выбрасывается
- "catch" блок извлекает исключение и создает объект ($e) , содержащую информацию об исключении
- Сообщение об ошибке с исключением вторит вызова $e-> getMessage() из объекта исключения
Тем не менее, один из способов , чтобы обойти "every throw must have a catch" правило , чтобы установить верхний обработчик исключений уровня для обработки ошибок, проскочить.
Создание класса пользовательских исключений
Для создания обработчика исключений необходимо создать специальный класс с функциями, которые могут быть вызваны, когда исключение происходит в PHP. Класс должен быть расширением класса исключений.
Пользовательский класс исключения наследует свойства от класса исключений в 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();
}
?>
Новый класс является копией старого класса исключений с добавлением errorMessage() функции. Так как копия старого класса, и он наследует свойства и методы от старого класса, мы можем использовать методы класса исключения , как getLine() и getFile() и getMessage() .
Объяснение примера:
Код выше генерирует исключение, и ловит его с пользовательским классом исключений:
- customException() класса создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства от старого класса исключений
- errorMessage() функция создается. Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недействительным
- Переменная $ электронной почты устанавливается на строку, которая не является действительным адресом электронной почты
- "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();
}
?>
Объяснение примера:
Код выше проверяет два условия и генерирует исключение, если какие-либо из условий не выполняется:
- customException() класса создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства от старого класса исключений
- errorMessage() функция создается. Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недействительным
- Переменная $ электронной почты устанавливается на строку , которая является адрес электронной почты, но содержит строку "example"
- "try" блок выполняется , и исключение не брошено на первое условие
- Второе условие вызывает исключение , так как электронная почта содержит строку "example"
- "catch" блок перехватывает исключение и выводит правильное сообщение об ошибке
Если исключение брошено было класс customException и не было customException поймать, только улов базы исключения, исключение будет обработано там.
Повторное создание исключений
Иногда, когда исключение, вы можете обращаться иначе, чем стандартный способ. Можно бросить исключение во второй раз в "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" в нем, если это произойдет, исключение повторно брошено:
- customException() класса создается как расширение старого класса исключений. Таким образом, он наследует все методы и свойства от старого класса исключений
- errorMessage() функция создается. Эта функция возвращает сообщение об ошибке, если адрес электронной почты является недействительным
- Переменная $ электронной почты устанавливается на строку , которая является адрес электронной почты, но содержит строку "example"
- "try" блок содержит еще один "try" блок , чтобы сделать возможным повторно бросить исключение
- Исключение срабатывает , так как электронная почта содержит строку "example"
- "catch" блок перехватывает исключение и повторно бросает "customException"
- "customException" пойман и отображает сообщение об ошибке
Если исключение не перехвачено в его нынешнем "try" блок, он будет искать водосборный блок на "higher levels" .
Установить Exception Handler Top Level
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" блок. Вместо этого обработчик исключений верхнего уровня срабатывает. Эта функция должна использоваться, чтобы поймать пойманные исключения.
Правила исключений
- Код может быть окружен в Ьге блоке, чтобы помочь поймать потенциальные исключения
- Каждый блок или попробовать "throw" должен иметь по крайней мере один соответствующий блок улова
- Несколько блоков улов может быть использован, чтобы поймать различные классы исключений
- Исключения могут быть брошены (or re-thrown) в водосборном блоке в Ьге блока
Простое правило: Если бросить что-то, вы должны поймать его.