PHP5.5: Try/Catch/Finally

Обработка исключений доступна в PHP, начиная с 5-ой версии. Это позволяет иметь более предсказуемый код в случае, если что-то идет не так и возникает исключение. Но, начиная с версии 5.5, обработка исключений развилась до того уровня, каким язык должен был обладать с самого начала, а именно, появилась “finally“-часть

Начнем с простого примера, что именно finally делает:

Выброшено ли исключение или нет, но finally-блок всегда будет отрабатывать. Это позволяет нам делать определенного рода очистку или другие логичные действия. Кто-то может возразить, что то же самое можно просто сделать, добавив логику finally-блока сразу под блок try/catch. Но с finally не все так просто, как может показаться на первый взгляд.

Finally-блок всегда будет запущен до выхода из try/catch/finally. Представим, что у нас есть необработанное исключение:

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

Еще пример:

Заметили как внешний finally-блок тоже был вызван? Как было замечено ранее, finally-блок позволяет нам совершать некоторые локальные манипуляции. Это позволяет аккуратно группировать участки кода.

Finally и return: ставки приняты, ставок больше нет

Как уже говорилось, finally-блок всегда будет отрабатывать, независимо от того выброшено ли исключение или нет. Но что будет происходить, если мы встретим “return“? Конечно, finally-блок не будет вызван, ведь мы возвращаем значение функции? Что ж, на самом деле finally-блок все равно будет вызван до возвращения значения. Это то место, где происходит внутренняя магия, которая заключается в том, что само возвращения значения откладывается, запускается блок finally, а затем происходит возврат значения. Если выдумаете, что использование goto может запутать ваш код, то попробуйте использовать return в блоку try/catch/finally :)

И снова пример:

Finally все еще вызывается, даже когда try/catch возвращает значение. Но будьте осторожны с возвратом значений, так как они могут стать серьезной причиной для множества проблем, которые трудно отловить.

Этот кусок кода – отличный вопрос на вашем следующем тесте  Zend Certified Exam :) Что вернет функция foobar()? Давайте представим, что имеет место исключение, тогда мы перемещаемся в секцию catch, где находим “return 2″. Но как мы уже выяснили, перед тем как покинуть функцию и вернуть значение, PHP должен запустить finally-блок. Внутри этого блока есть “return 3″. В этом случае, PHP перезапишет любые отложенные return-значения, и в итоге вернет “3″. Правильный ответ “3″.

Выглядит довольно просто. Но существует множество ситуаций, где что-то может пойти не так, когда вы используете “return”. Вот 3 правила, в курсе которых вы должны быть, когда используете return.

Отложенные return могут быть перезаписаны другими return.

Как в нашем последнем примере, значение внутри finally-блок перезаписывает значение из try/catch блока.

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

Если исключение не обработано, то в обычной ситуации оно будет передано родителю (и так до тех пор пока мы не достигнем низов и PHP выбросит необработанное исключение). Но постольку поскольку мы возвращаем значение внутри try/catch/finally блока, исключение не будет передано родителю, даже если оно не обработано текущей секцией try/catch

Отложенные return все равно вычисляются заблаговременно.

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

Например:

Тут функции bar2() и bar3() вызваны, несмотря на то, что значение bar2() никогда не будет возвращено.

В заключении

“Finally” – это то, что вы будете использовать со временем все чаще и чаще и на то есть причины. Но будьте осторожны с использованием return. Они могут серьезно запутать ваш код, и их очень сложно отследить в таком случае. Просто следуйте трем правилам и все будет в порядке.

Источник

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">