Исключения

Модель исключений (exceptions) в PHP 5 схожа с используемыми в других языках программирования. Исключение можно сгенерировать (как говорят, "выбросить") при помощи оператора throw, и можно перехватить (или, как говорят, "поймать") оператором catch. Код генерирующий исключение, должен быть окружен блоком try, для того чтобы можно было перехватить исключение. Каждый блок try должен иметь как минимум один соответствующий ему блок catch или finally.

Генерируемый объект должен принадлежать классу Exception или наследоваться от Exception. Попытка сгенерировать исключение другого класса приведет к неисправимой ошибке.

catch

Можно использовать несколько блоков catch, перехватывающих различные классы исключений. Нормальное выполнение (когда не генерируются исключения в блоках try или когда класс сгенерированного исключения не совпадает с классами, объявленными в соответствующих блоках catch) будет продолжено за последним блоком catch. Исключения так же могут быть сгенерированы (или вызваны еще раз) оператором throw внутри блока catch.

При генерации исключения код следующий после описываемого выражения исполнен не будет, а PHP предпримет попытку найти первый блок catch, перехватывающий исключение данного класса. Если исключение не будет перехвачено, PHP выдаст сообщение об ошибке: "Uncaught Exception ..." (Неперехваченное исключение), если не был определен обработчик ошибок при помощи функции set_exception_handler().

finally

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

Наследование исключений

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

<?php
class Exception
{
    protected $message = 'Unknown exception';   // Сообшение
    private   $string;                          // Свойство для __toString
    protected $code = 0;                        // Код исключения, 
                                                // определяемый пользователем
    protected $file;                            // Файл в котором было
                                                // выброшено исключение
    protected $line;                            // Строка в которой было
                                                // выброшено исключение
    private   $trace;                           // Трассировка вызовов методов и функций 
    private   $previous;                        // Предыдущее исключение, для
                                                // вложенных блоков try

    public function __construct($message = null, $code = 0, Exception $previous = null);

    final private function __clone();           // Запрещает клонировать исключения

    final public  function getMessage();        // Возвращает сообшение исключения 
    final public  function getCode();           // Код исключения
    final public  function getFile();           // Файл, где выброшено исключение
    final public  function getLine();           // Строка, выбросившая исключени
    final public  function getTrace();          // Массив backtrace()
    final public  function getPrevious();       // Предыдущее исключение
    final public  function getTraceAsString();  // Трассировка вызовов как строка

    // Переопределяемое
    public function __toString();               // форматированная строка для отображения
}
?>

Если класс, наследуемый от Exception переопределяет конструктор, необходимо вызвать в конструкторе parent::__construct(), чтобы быть уверенным, что все дынные будут доступны. Метод __toString() может быть переопределен, что бы обеспечить нужный вывод, когда объект преобразуется в строку.

Замечание: Исключения нельзя клонировать. Попытка клонировать исключение приведет к неисправимой ошибке E_ERROR.

set_exception_handler()

  • Задает обработчик по умолчанию для случаев, когда исключение выброшено вне блока try/catch. После вызова exception_handler выполнение будет остановлено.
  • Возвращает имя предыдущего заданного обработчика или NULL в случае ошибки. Если предыдущих обработчиков определено не было, то также возвращается NULL.

Ошибки можно преобразовать в исключения с помощью класса ErrorException.