PHP Обработка исключений
Исключения используются для изменения нормального потока выполнения скрипта при возникновении определенной ошибки.
Что такое исключение
PHP 5 предоставляет новый объектно-ориентированный метод обработки ошибок.
Обработка исключений используется для изменения нормального потока выполнения скрипта при возникновении определенного состояния ошибки (исключения). Это состояние называется исключением.
При возникновении исключения обычно происходит следующее:
- Текущее состояние кода сохраняется
- Выполнение кода переключается на предопределённую (пользовательскую) функцию-обработчик исключений
- В зависимости от ситуации обработчик может возобновить выполнение кода с сохранённого состояния кода, завершить выполнение скрипта или продолжить выполнение скрипта с другого места в коде
Мы покажем различные методы обработки ошибок:
- Базовое использование исключений
- Создание пользовательского обработчика исключений
- Множественные исключения
- Повторный выброс исключений
- Установка обработчика исключений верхнего уровня
Примечание:Исключения следует использовать только в ситуациях ошибок и не следует использовать для перехода в другое место кода в определённой точке.
Базовое использование исключений
Когда выбрасывается исключение, код после него не будет продолжать выполняться, и PHP попытается найти соответствующий блок «catch».
Если исключение не перехвачено и для соответствующей обработки не используется set_exception_handler(), то возникнет серьёзная ошибка (фатальная ошибка), и будет выведено сообщение об ошибке «Uncaught Exception».
Давайте попробуем вызвать исключение, не перехватывая его:
Приведённый выше код вызовет ошибку, подобную этой:
Fatal error: Uncaught exception 'Exception' with message 'Value must be 1 or below' in /www/example/test/test.php:7 Stack trace: #0 /www/example/test/test.php(13): checkNum(2) #1 {main} thrown in /www/example/test/test.php on line 7
Try, throw и catch
Чтобы избежать ошибки, появившейся в примере выше, нам нужно создать подходящий код для обработки исключений.
Подходящий код обработки исключений должен включать:
- Try - Функция, использующая исключение, должна находиться внутри блока "try". Если исключение не вызвано, код продолжит выполнение как обычно. Но если исключение вызвано, выбрасывается исключение.
- Throw - указывает, как вызвать исключение. Каждый "throw" должен соответствовать как минимум одному "catch".
- Catch — блок "catch" перехватывает исключение и создаёт объект, содержащий информацию об исключении.
Давайте вызовем исключение:
Приведённый выше код вызовет ошибку, подобную этой:
Message: 变量值必须小于等于 1
Пояснение к примеру:
Код выше выбросил исключение и перехватил его:
- Создайте функцию checkNum(). Она проверяет, больше ли число 1. Если да, она выбрасывает исключение.
- Вызовите функцию checkNum() в блоке "try".
- В функции checkNum() выбрасывается исключение.
- Блок "catch" получает исключение и создаёт объект, содержащий информацию об исключении ($e).
- Вызвав $e->getMessage() для этого объекта исключения, выведите сообщение об ошибке из этого исключения.
Однако, чтобы следовать принципу «каждый throw должен соответствовать catch», можно установить обработчик исключений верхнего уровня для обработки пропущенных ошибок.
Создание пользовательского класса исключений
Создание пользовательского обработчика исключений очень просто. Мы просто создаём специальный класс, функции которого могут вызываться при возникновении исключения в PHP. Этот класс должен быть расширением класса исключений.
Этот пользовательский класс customException наследует все свойства класса исключений PHP, и вы можете добавить в него пользовательские функции.
Давайте начнём создавать класс customException:
Этот новый класс — это копия старого класса исключений вместе с функцией errorMessage(). Поскольку он является копией старого класса, он наследует свойства и методы старого класса, и мы можем использовать методы класса исключений, такие как getLine(), getFile() и getMessage().
Пояснение к примеру:
Приведённый выше код выбросил исключение и перехватил его с помощью пользовательского класса исключений:
- Класс customException() создан как расширение старого класса исключений. Таким образом, он наследует все свойства и методы старого класса исключений.
- Создайте функцию errorMessage(). Если адрес e-mail недействителен, эта функция возвращает сообщение об ошибке.
- Присвойте переменной $email строку с недействительным адресом e-mail.
- Выполняется блок "try", и поскольку адрес электронной почты недействителен, выбрасывается исключение.
- Блок "catch" перехватывает исключение и отображает сообщение об ошибке.
Множественные исключения
Несколько исключений можно использовать, чтобы скрипт мог обнаруживать несколько ситуаций.
Вы можете использовать несколько блоков if..else, или блок switch, или вложить несколько исключений. Эти исключения могут использовать разные классы исключений и возвращать разные сообщения об ошибках:
Пояснение к примеру:
Приведенный выше код проверяет два условия, и если любое из условий не выполнено, выбрасывается исключение:
- Класс customException() создан как расширение старого класса исключений. Таким образом, он наследует все свойства и методы старого класса исключений.
- Создайте функцию errorMessage(). Если адрес e-mail недействителен, эта функция возвращает сообщение об ошибке.
- Присвойте переменной $email строку, которая является допустимым адресом электронной почты, но содержит строку "example".
- Выполните блок "try"; при первом условии исключение не выбрасывается.
- Поскольку адрес электронной почты содержит строку "example", второе условие вызывает исключение.
- Блок "catch" перехватывает исключение и отображает соответствующее сообщение об ошибке.
Если класс customException выбрасывает исключение, но customException не перехватывается, а перехватывается только базовое исключение, то исключение обрабатывается там.
Повторный выброс исключений
Иногда, когда выбрасывается исключение, вы можете захотеть обработать его иначе, чем стандартным способом. Вы можете перебросить исключение в блоке "catch".
Скрипты должны скрывать системные ошибки от пользователей. Системные ошибки могут быть важны для программистов, но пользователям они не интересны. Чтобы упростить работу пользователям, можно перебросить исключение с понятным пользователю сообщением:
Пояснение к примеру:
Приведённый выше код проверяет, содержит ли адрес электронной почты строку "example". Если да, исключение выбрасывается повторно:
- Класс customException() создаётся как расширение старого класса исключений. Таким образом он наследует все свойства и методы старого класса исключений.
- Создайте функцию errorMessage(). Если адрес электронной почты недействителен, эта функция возвращает сообщение об ошибке.
- Присвойте переменной $email строку, которая является допустимым адресом электронной почты, но содержит строку "example".
- Блок "try" содержит другой блок "try", чтобы исключение можно было выбросить снова.
- Поскольку адрес электронной почты содержит строку "example", исключение срабатывает.
- Блок "catch" перехватывает исключение и повторно выбрасывает "customException".
- "customException" перехватывается, и отображается сообщение об ошибке.
Если исключение не перехвачено в текущем блоке "try", оно будет искать блок catch на более высоком уровне.
Установка обработчика исключений верхнего уровня
Функция set_exception_handler() может задать определяемую пользователем функцию, которая обрабатывает все неперехваченные исключения.
Вывод приведённого выше кода следующий:
Exception: Uncaught Exception occurred
В приведённом выше коде нет блока "catch"; вместо этого запускается обработчик исключений верхнего уровня. Эта функция должна использоваться для перехвата всех исключений, которые не перехвачены.
Правила обработки исключений
- Код, требующий обработки исключений, следует размещать внутри блока try, чтобы перехватывать потенциальные исключения.
- Каждый блок try или throw должен иметь как минимум один соответствующий блок catch.
- Использование нескольких блоков catch позволяет перехватывать разные виды исключений.
- Исключение может быть выброшено (повторно выброшено) в блоке catch внутри блока try.
Короче говоря: если исключение выброшено, оно должно быть перехвачено.
Другие расширения