Исключения в PHP 7

С PHP 7 к нам приходит новая эпоха обработки исключений. Впервые PHP стал выкидывать исключения для фатальных и восстанавливаемых фатальных ошибок. Теперь мы можем их обрабатывать, как захотим. Больше никаких @, include, file_exists и прочей не логичности в коде.

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

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

Новые исключения Error

Как вы уже смогли заметить из таблицы иерархий, в PHP 7 добавились новые исключения для отлавливания фатальных (E_ERROR) и восстанавливаемых ошибок (E_RECOVERABLE_ERROR).
Но к сожалению, определенные ошибки, например «out of memory», по прежнему приведут к остановке, как их вообще обрабатывать? 😀

Error

Все фатальные ошибки будут выбрасывать исключение расширяющие Error исключения. Ошибки при этом, будут выведены как и раньше, если исключение не обработано.

AssertionError

В PHP 7, есть усовершенствование утверждений, используя assert() функцию, с добавлением нулевой стоимостью утверждений, и выбрасыванием исключений. Для включения данной возможности, нужно установить параметр assert.exception = 1 в php.ini (или с использованием ini_set()).

ParseError

Благодаря выкидыванию исключений ParseError при ошибке включения файла, теперь можно обработать поведение:

TypeError

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

Отлавливаем фатальные ошибки в PHP7

Еще одно важное изменение PHP7 в отлавливании фатальных ошибок. Раньше, они ловились и обрабатывались с использованием set_error_handler(). Теперь, в PHP 7, они выкидывают Error исключения, и если, исключения не будут обработаны, то выбрасывается реальная фатальная ошибка, которая больше не будет доступна в set_error_handler().

Это было сделано для обратной совместимости и для работы в PHP 5.x и 7, вы должны использовать bothset_error_handler() и try... catch.

Использование Throwable

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

Но это еще не вся история, есть лайфхак, который не рекомендуется к использованию. Вы можете расширить интерфейс Throwable  — а уже потом, реализовать свои исключения типов Error или Exception используя свой расширенный интерфейс.

Заключение

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

https://wiki.php.net/rfc/throwable-interface