Правильная работа с исключениями в PHP / Хабр
В предыдущей статье я предложил свести все «механизмы ошибок» к исключениям, поэтому логично будет объяснить, как правильно работать с исключениями в PHP.Сначала поясню, почему я выбрал именно исключения, как механизм работы с ошибками:
- Исключения — это гибкий, расширяемый метод обработки ошибок;
- Это стандартизованный механизм – человеку, не работавшему с вашим кодом, не нужно будет читать мануал, чтобы понять, как обрабатывать ошибки. Ему достаточно знать, как работают исключения;
- С исключениями гораздо проще находить источник ошибок, так как всегда есть стек вызовов (trace).
1. Никогда не бросайте абстрактное исключение (т.
class baseException extends Exception{}и замените все строки в своем коде
throw new Exception();на
throw new baseException();Таким образом, все исключения вашего кода можно будет отличить от исключений не вашего кода.
2. Исключения должны быть иерархичны. У вас должен быть базовый класс исключений, от которого наследуются все исключения, бросаемые в вашем коде. Например, у вас в коде есть модуль для работы с файлами fileModule, объявите исключение, которое будет бросаться только этим модулем
class fileModuleException extends baseException{}Если вам нужна еще бОльшая различимость ошибок, например, среди всех ошибок, связанных с работой с файлами, вы хотите различать ситуацию, когда файл не найден, то нужно объявить еще одно исключение
class fileNotFoundException extends fileModuleException{}Соблюдая иерархичность, вы сможете различать исключения от разных модулей в вашем приложении. Я не призываю наплодить кучу исключений, для каждого модуля. Исключения должны проектироваться не от кода, а от ситуаций, которые вы хотите по-особенному обработать.
try{Чтобы такие ситуации в принципе не были возможны, можно «заглушить» code в базовом классе
//…
}catch(fileModuleException $e){
switch($e->getCode()){//так делать не надо
case 1: echo ‘file not found’;
case 2: echo ‘file not readable’;
//…
}
}
function __construct($message = », $code = 0) {
parent::__construct($message, 0);}
3. Не обрабатывайте исключения, если в данном контексте не понятно, как его обработать. Например, если вы следуете паттерну MVC, то в методе модели может быть не понятно, как обработать ошибку — как ее вывести, потому как за логику отвечает control, а за вывод view. Если не понятно, что делать с исключением, то «пробросьте» его дальше.
try{От метода, который пробрасывает исключения, можно ожидать любых исключений. Можно сузить количество исключений, бросаемых методом, преобразовав исключение:
$db->begin();
//…
$db->commit();
}catch(Exception $e){
$db->rollback();
throw $e;
}
try{Тут очень важный момент — не разрывать цепь исключений. Третьим параметром передается изначальное исключение. Этот код нативно работает в 5.3 и с доработкой в 5.2. При таком подходе стек вызовов будет «цельным» от самого первого броска исключения.
//…
}catch(Exception $e){
throw new baseException($message, 0, $e);//не разрывайте цепь
}
4. У вас должен быть глобальный обработчик исключений. Это может быть или try…catch на самом верхнем уровне или ExceptionHandler.
5. Исключение это объект, соответственно его можно расширять под свои потребности. Допустим у вас многоязычное приложение и текст ошибки в бросаемом исключении нужно выводить пользователю. Соответственно это сообщение нужно переводить. Это не сложно, если сообщение без переменных частей, например, «Ошибка при выполнении операции». Но что делать, если в сообщение входят переменные части, например, «У вас недостаточно денег на балансе (1000). Нужно 2000». Тогда можно отдельно передать шаблон текста ошибки и отдельно сами переменные. Пример кода .
6. Преобразуйте все ошибки утверждений (assertion fail) и не фатальные ошибки в исключения (см. мою предыдущую статью)
7. Никогда не глушите исключения без какой либо обработки
try {потому, что в противном случае ошибку из-за таких действий будет очень сложно найти. Нужно хотя бы логировать:
//. ..
} catch (Exception $e) {
//ничего делаем
}
try {//…
} catch (Exception $e) {
exceptionHandlerClass::exceptionLog($e);
}
8. Документируйте исключения. Указывайте в докблоке, какие исключения выбрасывает метод (таг @throws, можно указывать больше одного). Это упростит всем жизнь.
Вот в принципе и все, что нужно знать про исключения. Еще один интересный факт напоследок — исключения можно ловить по интерфейсу:
interface iException{}
class customException extends baseException implements iException{}
try{
//…
}catch(iException $e){
//…
}
UPD исправлены замечания в комментариях:1, 2 и 3 (спасибо всем, кто поучаствовал в обсуждении).
Урок 15.
PHP — ООП. Обработчик ошибок (error handler). Исключения (exceptions)- Главная >
- Видео канал >
УЛУЧШАЙТЕ НАВЫКИ С ПОМОЩЬЮ ПРАКТИКУМА
СЛЕДУЮЩЕЕ15й урок курса из 16ти уроков. Курс подойдет новичкам, которые хотят максимально быстро въехать в современные принципы программирования на php. Разбираем механизм обработки ошибок в php. Говорим об исключениях.
Please enable JavaScript to view the comments powered by Disqus.Регистрация через
✖или E-mail
Нажав на кнопку «Зарегистрироваться»,
Вы соглашаетесь с условиями использования.
Уже есть аккаунт
Получите курс бесплатно
✖
Вы выбрали курс для изучения
«»
Чтобы получить доступ к курсу, зарегистрируйтесь на сайте.
РЕГИСТРАЦИЯ
Спасибо за регистрацию
Перейдите на почту и подтвердите Ваш аккаунт,
чтобы получить доступ ко всем
бесплатным урокам и вебинарам на сайте ITVDN. com
ПОДТВЕРДИТЬ ПОЧТУ НАЧАТЬ ОБУЧЕНИЕ
Спасибо за регистрацию
✖
Ваш аккаунт успешно подтвержден.
Начать обучение вы можете через Личный кабинет
пользователя или непосредственно на странице курса.
НАЧАТЬ ОБУЧЕНИЕ
Подтверждение аккаунта
На Ваш номер телефона было отправлено смс с кодом активации аккаунта. Пожалуйста, введите код в поле ввода.
Отправить код еще раз
Изменить номер телефона
Ошибка
✖PHP: Исключение — вручную
Изменение языка: английскийбразильский португальскийкитайский (упрощенный)французскийнемецкийяпонскийрусскийиспанскийтурецкийДругое
Отправить запрос на вытягивание Сообщить об ошибке
(PHP 5, PHP 7, PHP 8)
Введение
Исключение — это базовый класс для все пользовательские исключения.
Обзор класса
класс Исключение реализует Метательный {
защищено нить $ сообщение =»»;
частный нить $ строка =»»;
защищенный инт $ код ;
защищенный нить $ файл =»»;
защищенный инт $ строка ;
частный множество $ трассировка = [];
частный ? Бросаемый $ предыдущий = ноль;
public __construct(string $message
= «», int $code
= 0,? Throwable $previous
= null
)final public getMessage(): string
окончательный публичный getPrevious(): ?Throwable
final public getCode(): int
final public getFile(): string
final public getLine(): int
final public getTrace(): array
final public getTraceAsString(): string
открытый __toString(): строка
частный __clone(): недействительный
}Свойства
- сообщение
Сообщение об исключении
- код
Код исключения
- файл
Имя файла, в котором было создано исключение
- строка
Строка, в которой было создано исключение
- предыдущий
Предыдущее исключение
- струна
Строковое представление трассировки стека
- след
Трассировка стека в виде массива
Table of Contents
- Exception::__construct — создание исключения
- Exception::getMessage — получение сообщения об исключении Код исключения
- Exception::getFile — Получает файл, в котором было создано исключение
- Exception::getLine — Получает строку, в которой было создано исключение
- Exception::getTrace — Получает трассировку стека
- Exception::getTraceAsString — Получает трассировку стека в виде строки
- Exception::__toString — Строковое представление исключения
- Exception::__clone — Клонирование исключения
+ добавить примечание
Пользовательские заметки 3 заметки
вверх
вниз
96
Whysteepy на Gmail точка com ¶5 лет назад
Списки Throwable и дерева исключений по состоянию на 7. 2.0 Error
ArithmeticError
DivisionByZeroError
AssertionError
ParseError
TypeError
ArgumentCountError
Exception
ClosedGeneratorException
DOMException
ErrorException
IntlException
LogicException
BadFunctionCallException
BadMethodC allException
DomainException
InvalidArgumentException
LengthException
OutOfRangeException
PharException
ReflectionException
RuntimeException
OutOfBoundsException
OverflowException
PDOException 90 . 4d1ca980848e6a
https ://3v4l.org/sDMsv
размещено кем-то здесь http://php.net/manual/en/class.throwable.php
вверх
вниз
36
cHao ¶8 лет назад
Обратите внимание, что свойства исключения заполняются при *создании* исключения, а не при его создании. Бросание исключения, похоже, не изменяет их. Среди прочего это означает:
* Исключение будет винить строку, которая его создала, а не строку, которая его выдала.
* В отличие от некоторых других языков, повторное создание исключения не портит трассировку.
* Сгенерированное и не сгенерированное исключение выглядят в основном одинаково. На моей машине единственное видимое отличие состоит в том, что выброшенное исключение имеет свойство `xdebug_message`, а не выброшенное – нет. Конечно, если у вас не установлен xdebug, вы даже этого не получите.
вверх
вниз
5
shaman_master в списке точка ru ¶3 года назад
Примечание: эта документация неполная, ReflectionObject::export($exception):
Объект класса [ class Exception реализует Throwable ] {
- Properties [7] {
Property [ protected $message ]
Property [ private $ строка ]
Свойство [ защищенный $ код ]
Свойство [ защищенный $ файл ]
Свойство [ защищенная $ строка ]
Свойство [ частный $ след ]
Свойство [ частный $ предыдущий ]
}
– Методы [11] {
Метод [ final private method __clone ] {
} Метод [ public method __construct ] {
– Параметры [3] {
Параметр #0 [ $message ]
Параметр #1 [ $ code ]
Parameter #2 [ $previous ]
}
}
Method [ public method __wakeup ] {
}
Method [ final public method getMessage ] {
}
Метод [конечный общедоступный метод getCode ] {
}
Метод [конечный общедоступный метод getFile ] {
}
Метод [конечный общедоступный метод getLine ] {
}
Метод [конечный общедоступный метод getTrace ] { 902 03 }
Method [ final public method getPrevious ] {
}
Метод [final public method getTraceAsString ] {
}
Method [ public method __toString ] {
}
}
}
?>
Пропущено:
Свойство [ private $string ]
Property [ private $trace ]
Property [ private $previous ]
Method [ public method __wakeup ] {
}
+ добавить примечание
Исключения или ошибки | Инструменты PHP для документации Visual Studio
PHP сообщает об ошибках, предупреждениях и уведомлениях, когда программа оказывается в неожиданном состоянии. Начиная с PHP7, это сообщение об ошибке в основном передается путем создания исключения.
Инструменты PHP для отладчика Visual Studio поддерживают оба типа обработки ошибок — традиционные ошибки PHP и исключения PHP.
Перерыв при возникновении исключения
Вы можете указать отладчику прерывать работу при возникновении исключения, что позволит вам проверить текущее состояние программы.
При открытом проекте PHP используйте Отладка | Окна | Настройки исключений
, чтобы открыть окно Настройки исключений . Найти исключений PHP и убедитесь, что исключение, которое вы хотите прервать, отмечено флажком. Если исключение не указано в настройках исключений, отметьте пункт или вы можете проверить всю категорию Исключения PHP** .
В окне Настройки исключений вы также можете найти Ошибка , Предупреждение , Уведомление , которые являются не исключениями, а традиционными ошибками PHP. Они не разбиты на конкретные ошибки. Но вы можете включить/отключить их как целую категорию.
Затем, когда вы отлаживаете программу PHP, Visual Studio прервется при возникновении исключения так же, как если бы в этом месте присутствовала точка останова.
В диалоговом окне обработчика исключения будет представлена информация об исключении, например тип исключения и сообщение. Вы можете проверить программу, оценить выражения, проверить стек вызовов и т. д.
Примечание: вы можете снять отметку Прервать при возникновении этого типа исключения прямо в обработчике исключений и продолжить отладку (нажмите F5 ). Visual Studio добавит этот тип исключения в настройки исключения и запомнит, что это исключение больше не должно прерываться.
Добавить или удалить исключение в настройках исключений
Настройки исключений перечисляют лишь несколько распространенных типов исключений. Скорее всего, вы не найдете в списке конкретное исключение, на котором хотите остановиться. Вы можете либо проверить или выберите исключение, которое вы хотите отключить.
Обычно нет необходимости явно добавлять исключение в список, так как вы можете лениво решить, что делать с исключением при его первом появлении. и отладчик может добавить его в настройки исключений для вас.
Если вы хотите заблаговременно добавить (или удалить) исключение, в окне Настройки исключений выберите категорию Исключения PHP и нажмите кнопку «Добавить» (или кнопку «Удалить»).
Введите полное имя исключения (включая пространства имен). Убедитесь, что имя указано правильно, отладчик не проверяет, правильно ли вы написали тип исключения.
Необработанные исключения и фатальные ошибки
Когда исключение не обрабатывается в пользовательском коде и в конечном итоге обрабатывается самим PHP, оно становится необработанным, и программа завершается.