php try catch несколько исключений

Правильная работа с исключениями в PHP

class baseException extends Exception

Таким образом, все исключения вашего кода можно будет отличить от исключений не вашего кода.

2. Исключения должны быть иерархичны. У вас должен быть базовый класс исключений, от которого наследуются все исключения, бросаемые в вашем коде. Например, у вас в коде есть модуль для работы с файлами fileModule, объявите исключение, которое будет бросаться только этим модулем

class fileModuleException extends baseException

class fileNotFoundException extends fileModuleException < >

3. Не обрабатывайте исключения, если в данном контексте не понятно, как его обработать. Например, если вы следуете паттерну MVC, то в методе модели может быть не понятно, как обработать ошибку — как ее вывести, потому как за логику отвечает control, а за вывод view. Если не понятно, что делать с исключением, то «пробросьте» его дальше.

Тут очень важный момент — не разрывать цепь исключений. Третьим параметром передается изначальное исключение. Этот код нативно работает в 5.3 и с доработкой в 5.2. При таком подходе стек вызовов будет «цельным» от самого первого броска исключения.

4. У вас должен быть глобальный обработчик исключений. Это может быть или try. catch на самом верхнем уровне или ExceptionHandler. Все исключения, которые добрались до глобального обработчика, считаются критическими, так как не были правильно обработаны ранее. Их надо залогировать.

5. Исключение это объект, соответственно его можно расширять под свои потребности. Допустим у вас многоязычное приложение и текст ошибки в бросаемом исключении нужно выводить пользователю. Соответственно это сообщение нужно переводить. Это не сложно, если сообщение без переменных частей, например, «Ошибка при выполнении операции». Но что делать, если в сообщение входят переменные части, например, «У вас недостаточно денег на балансе (1000). Нужно 2000». Тогда можно отдельно передать шаблон текста ошибки и отдельно сами переменные. Пример кода Старый пример кода.

6. Преобразуйте все ошибки утверждений (assertion fail) и не фатальные ошибки в исключения (см. мою предыдущую статью)

7. Никогда не глушите исключения без какой либо обработки

8. Документируйте исключения. Указывайте в докблоке, какие исключения выбрасывает метод (таг @throws, можно указывать больше одного). Это упростит всем жизнь.

Вот в принципе и все, что нужно знать про исключения. Еще один интересный факт напоследок — исключения можно ловить по интерфейсу:

UPD исправлены замечания в комментариях:1, 2 и 3 (спасибо всем, кто поучаствовал в обсуждении).
Отдельное спасибо, хабраюзеру ckopobapkuh за активное участие

Источник

Исключения PHP: Try Catch для обработки ошибок

Что такое исключение?

Здесь важно отметить, что обработка исключений отличается от обработки ошибок. При обработке ошибок мы можем использовать функцию set_error_handler для установки нашей настраиваемой функции обработки ошибок, чтобы всякий раз, когда срабатывает ошибка, она вызывала нашу функцию обработки ошибок. Таким образом, вы можете управлять ошибками. Однако, как правило, некоторые виды ошибок не восстанавливаются и прекращают выполнение программы.

Поток управления обработкой исключений

Давайте рассмотрим следующую диаграмму, которая показывает общий поток управления обработкой исключений.

php try catch несколько исключений. Смотреть фото php try catch несколько исключений. Смотреть картинку php try catch несколько исключений. Картинка про php try catch несколько исключений. Фото php try catch несколько исключенийphp try catch несколько исключений. Смотреть фото php try catch несколько исключений. Смотреть картинку php try catch несколько исключений. Картинка про php try catch несколько исключений. Фото php try catch несколько исключений php try catch несколько исключений. Смотреть фото php try catch несколько исключений. Смотреть картинку php try catch несколько исключений. Картинка про php try catch несколько исключений. Фото php try catch несколько исключений

Выброс исключения

Исключение может быть вызвано функцией, которую вы вызываете, или вы можете использовать ключевое слово throw для выбрасывания исключения вручную. Например, вы можете проверить некоторый ввод перед выполнением любой операции и выбросить исключение, если данные недействительны.

В следующем разделе мы рассмотрим пример из реального мира, чтобы понять, как работает обработка исключений.

Пример из реального мира

В этом разделе мы построим реальный пример для демонстрации обработки исключений в PHP.

Предположим, что вы создали приложение, которое загружает конфигурацию приложения из файла config.php. Теперь важно, чтобы файл config.php присутствовал, когда ваше приложение загружается. Таким образом, ваше приложение не может работать, если файл config.php отсутствует. Так что это идеальный случай, чтобы выбросить исключение и сообщить пользователю, что им необходимо исправить проблему.

Как вы можете видеть в приведенном выше примере, мы проверяем наличие файла config.php в начале фазы начальной загрузки. Если файл config.php найден, выполнение продолжается в обычном режиме. С другой стороны, мы выбросим исключение, если файл config.php не существует. Кроме того, мы хотели бы прекратить выполнение, если есть исключение!

Таким образом, это был пример обработки исключений с использованием класса Exception по умолчанию. В следующем разделе мы рассмотрим, как вы можете расширить основной класс Exception и создать свои собственные пользовательские исключения в своем приложении.

Как создавать пользовательские исключения

В этом разделе мы обсудим, как вы можете создавать пользовательские исключения в своих приложениях. Фактически, мы расширим пример, который мы только что обсуждали в предыдущем разделе, чтобы продемонстрировать пользовательские исключения.

В предыдущем примере мы выбрали исключение конфигурации, используя класс Exception по умолчанию. Это прекрасно, если вы просто хотите иметь дело с сообщением об ошибке. Однако иногда вы хотите сделать немного больше в зависимости от типа исключения, которое бросается. Вот почему пользовательские исключения полезны.

Перейдем к предыдущему примеру, как показано в следующем фрагменте.

Блок Finally

Попробуем понять это, используя следующий пример.

Заключение

Источник

Try Catch PHP или исключения в PHP

Давайте сразу взглянем на пример сгенерированного исключения ( и впоследствии перехваченного ):

Когда используются исключения?

Исключения используются, когда результат операции отличается от того, что ожидало ваше приложение. К примеру, если ваше приложение пытается прочитать CSV-файл на сервере, а этого файла не существует, то можно сгенерировать исключение. Использование PHP try catch в примере:

В приведенном выше примере использования в PHP try exception мы генерируем исключение тогда, когда не можем открыть запрашиваемый файл. И генерируем мы его, так как файл должен был существовать. Примеры ситуаций, когда вы можете генерировать исключения:

Нужно ли перехватывать все исключения?

Лично я так не считаю. К примеру: вам не удается подключиться к базе данных, и генерируется исключение, нужно ли тогда исполнять весь оставшийся код? Если весь последующий код привязан к базе данных, которой просто не существует, то зачем же его исполнять?

По моему мнению, исключения нужно перехватывать с помощью PHP try catch finally только, если это не оказывает негативного влияния на остальные функции приложения.

Например: если API-запрос к внешнему сервису выдает ошибку, то вы можете перехватить исключение и вывести дружественное пользователю сообщение « Невозможно подключиться к базе данных » или « Информация о погоде недоступна ».

Не перехваченные исключения следует обрабатывать с помощью пользовательского обработчика. Так вы сможете обрабатывать не перехваченные исключения, и выводить понятные человеку сообщения или заглушки.

Источник

Обработка исключений

Конструкция try catch finally

В процессе работы программы могут возникать различные ошибки, которые могут прервать работу программы. Например, рассмотрим следующую ситуацию:

Программа выводит результат деления. Поскольку делитель равен 0, а на ноль делить нельзя, то при выполнении деления программа завершится, и в браузере мы увидим что-то типа следующего:

Браузер отобразит нам произошедшую ошибку, причем дальше после строки с делением программа даже не будет выполняться.

Кто-то может сказать, что ситуация искуственная, так как мы сами определили делитель равный нулю. Но данные могут передаваться извне. Кроме того, кроме деления на ноль есть различные ситуации, при которых могут происходить ошибки. Но PHP предоставляет ряд возможностей для обработки подобных ситуаций.

Для обработки исключений в PHP применяется конструкция try-catch :

Например, обработаем ошибку с делением на ноль:

В итоге при выполнении программа выведет следующее:

Как видно из вывода программы, она не завершается аварийно при делении на ноль, а продолжает работу.

Типы ошибок и исключений

В PHP для разных ситуаций есть множество типов, которые описывают ошибки. Все эти встроенные типы применяют интерфейс Throwable :

php try catch несколько исключений. Смотреть фото php try catch несколько исключений. Смотреть картинку php try catch несколько исключений. Картинка про php try catch несколько исключений. Фото php try catch несколько исключений

Блок catch

Класс DivisionByZeroError унаследован от ArithmeticError, который, в свою очередь, унаследован от Error, реализующего интерфейс Throwable. Поэтому класс DivisionByZeroError представляет более конкретный тип и представляемые им ошибки должны обрабатываться в первую очередь. А тип Throwable представляет наиболее общий тип, так как ему соответствуют все возможные ошибки и исключения, поэтому блоки catch с таким типом должны идти в конце.

Если нам надо обрабатывать в принципе все ошибки и исключения, то мы можем определить только обработку общего для всех них типа Throwable:

Начиная с версии PHP 8.0 в блоке catch можно просто указать тип обрабатываемого исключения, не определяя переменную:

Получение информации об ошибках и исключениях

Интерфейс Throwable предоставляет ряд методов, которые позволяют получить некоторую информацию о возникшем исключении:

getMessage() : возвращает сообщение об ошибке

getCode() : возвращает код исключения

getFile() : возвращает название файла, в котором возникла ошибка

getLine() : возвращает номер строки, в которой возникла ошибка

getTrace() : возвращает трассировку стека

getTraceAsString() : возвращает трассировку стека в виде строки

Применим некоторые из этих методов:

Блок finally

Источник

codedokode / Зачем нужны исключения в PHP.md

Как использовать исключения в PHP

Если ты изучаешь ООП, ты наверняка натыкался на исключения. В мануале PHP описаны команды try / catch / throw и finally (доступна начиная с PHP 5.5), но не объясняется толком как их использовать. Чтобы разобраться с этим, надо узнать почему они вообще были придуманы.

А придуманы они были, чтобы сделать удобную обработку ошибок.

Для примера представим, что мы пишем приложение для вывода списка пользователей из файла на экран. Допустим, код выглядит как-то так:

Все ли тут верно? Нет, не все. Мы забыли сделать обработку ошибок. Файла может не существовать, к нему может не быть доступа, данные в нем могут быть в неверном формате. Хорошая программа, разумеется должна обрабатывать такие ситуации и выводить соответствующее сообщение.

Самый простой (но плохой) вариант — поместить код обработки и вывода ошибки прямо в loadUsersFromFile() :

Этот вариант плохой, так как теперь тот, кто вызывает функцию loadUsersFromFile не может никак повлиять на обработку ошибок. Может он хочет при ошибке вывести другое сообщение или хочет попробовать поискать файл в другом месте. Но наша функция просто завершает программу, не спрашивая его мнения. Это плохо.

Конечно, мы должны поменять и код, который вызывает функцию:

Теперь код гораздо лучше. Тот, кто вызывает функцию, может обрабатывать ошибки так, как ему хочется. Но за это нам пришлось заплатить усложнением кода: теперь мы должны после каждого вызова писать if и проверять, успешно ли выполнилась функция. Когда функций много, и каждая может вернуть ошибку, код начинает наполовину состоять из таких проверок.

В качестве решения проблемы были придуманы исключения. Если в функции произошла какая-то ошибка и она не может выполнить свою работу, то она выбрасывает исключение командой throw :

Исключение — это объект встроенного в PHP класса Exception (мануал по Exception) или его наследника. Объект исключения содержит подробности о причинах ошибки. Также, в PHP есть еще другие классы исключений, которые ты можешь использовать: http://php.net/manual/ru/spl.exceptions.php

Исключение выбрасывается в случае возникновения нештатной ситуации, когда функция обнаруживает что не способна выполнить свою задачу.

Исключение по умолчанию (если оно не перехватывается) выходит из всех вызовов функций до самого верха и завершает программу, выводя сообщение об ошибке. Таким образом, если ты не перехватываешь исключения, то все равно увидишь причину ошибки (а если у тебя установлено расширение xdebug то еще и стектрейс — цепочку вызовов функций, внутри которых оно произошло). И тебе больше не надо писать if:

Вот простой пример:

В данном примере кода исключение мгновенно выйдет из всех вложенных вызовов функций и завершит программу. Это хорошо, так как если произошла какая-то неисправимая ошибка, выполнять программу дальше нельзя. Это называется принципом fail fast (статья на Хабре).

Исключения можно «ловить». Это полезно в нескольких случаях. Иногда мы можем как-то отреагировать на неудачу: например, при ошибке скачивании файла по сети можно сделать паузу и повторить попытку. Для этого нам надо перехватить выброшенное функцией исключение.

Также, исключения обычно ловят на верхнем уровне программы в веб-приложениях для того, чтобы сделать свою страницу, информирующую об ошибке (так как PHP при непойманном исключении завершает программу, и пользователь видит пустую белую страницу в браузере, что плохо). В приложениях, запускаемых в командной строке, а не в браузере, обычно это не требуется, так как они не ориентированы на «обычных» пользователей.

Перехватывать исключения в теории можно двумя способами: неструктурно и структурно. Неструктурно — это когда мы задаем обработчик исключений в начале программы:

Этот способ ловит неперехваченные исключения любых видов во всей программе, его можно использовать для того, чтобы сделать свою страницу ошибки (об этом подробнее написано ниже). После срабатывания обработчика программа будет завершена, предотвратить это невозможно.

Перехватывать абсолютно любые типы исключений — плохая идея, так как мы обычно хотим обрабатывать только определенные, «наши», типы ошибок и не знаем что делать с другими. Чтобы перехватывать только нужные нам исключения, надо сделать свой класс на основе встроенного в PHP Exception :

Выкидывать его в throw

И ловить в catch только наши исключения:

Мы можем рассматривать исключения как часть интерфейса функции (часть правил работы с этой функцией). Есть аргументы, которые мы даем на вход, есть результат, который она возвращает, и есть исключения которые она может выкинуть при ошибке. И использование исключений позволяет пользователю функции (тому кто ее вызвал) решить что делать в случае ошибки.

Поддержка исключений везде

Многие разработчики забывают или ленятся проверять результат выполнения функции, и пишут некорректные программы, которые даже в случае ошибки пытаются продолжать выполнение. Это опасно, так как программа, в которой возникла ошибка, скорее всего будет дальше работать неправильно и выведет неточную информацию. Например, программа берет из базы сумму денег на счету пользователя, что-то меняет в ней и сохраняет ее обратно в базу. Если мы опечатаемся в имени переменной, может получиться так, что в базу мы запишем ноль. Хотя PHP и выведет предупреждение о несуществующей переменной, он не прерывает выполнения программы в этом случае.

Для этой проблемы есть решение. Можно установить общий обработчик ошибок (он вызывается при любой ошибке PHP, например обращении к несуществующей переменной или невозможности чтения файла), и в нем выкидывать исключение. Таким образом, любая ошибка или предупреждение приведут к выбросу исключения. Все это делается в несколько строчек с помощью встроенного в PHP класса ErrorException (мануал):

Этот код превращает любые ошибки и предупреждения PHP в исключения. Некоторые современные фреймворки (Slim) включают в себя такой код.

Чтобы расширение для работы с базами данных PDO использовало исключения (например при попытке выполнить неправильно написанный SQL запрос), надо установить соответствующий параметр (рекомендуется). Без него ты будешь должен после вызова каждой функции проверять результат с помощью if :

Исключения и mysqli

На мой взгляд это крайне неудачное решение, так как программист может забыть сделать проверку и ошибка останется полностью незамеченной, в итоге придется потратить больше времени на ее поиск.

Чтобы не писать ифы во всей программе, ты можешь сделать класс-обертку над mysqli. Или просто использовать PDO.

Так делать не надо

Не стоит ловить все исключения без разбора:

Лучше создать свой класс исключений и ловить только его.

Не надо скрывать информацию об ошибках. В 99% этот код, игнорирующий исключение, неправильный:

Не надо располагать try / catch и throw на одном уровне — в этом случае проще написать if :

Страница ошибки в веб-приложениях

По умолчанию при непойманном исключении PHP завершает скрипт. Если опция display_errors в php.ini равна 1, то PHP выводит подробности об исключении, а если она равна 0, то в браузере отображается просто белая страница. Также, PHP записывает информацию об исключении в лог ошибок сервера.

Очевидно что оба варианта не годятся для использования на продакшен («боевом») сервере: обычные пользователи не должны видеть непонятные надписи на английском о твоем приложении, и тем более не должны смотреть на пустую страницу и гадать в чем дело. А хакеры не должны видеть подробности об устройстве твоего приложения. Более того, PHP не выдает при ошибке HTTP код 500, который говорит роботам (вроде Гугла или Яндекса) что на странице ошибка и индексировать ее на надо. Разработчики PHP конечно выбрали неудачный способ поведения по умолчанию.

Потому на боевом сервере надо ставить display_errors в 0, а в приложении делать свою страницу ошибки.

Что будет, если просто не ловить исключение:

Как надо обрабатывать исключения:

Механизм исключений существует и в других языках в таком же виде: Java, C++, Ruby, Javascript и многих других. Статья в вики:

Также, про исключения можно почитать в книгах:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *