Estendendo exceções

Uma classe de exceção definida pelo usuário pode ser criada herdando a classe Exception. Os membros e propriedades abaixo mostram o que é acessível a partir da classe filha que deriva da Exception.

Example #1 A classe nativa Exception

<?php
class Exception implements Throwable
{
    protected $message = 'Unknown exception';   // Mensagem da exceção
    private   $string;                          // Cache __toString
    protected $code = 0;                        // Código definido pelo usuário
    protected $file;                            // Nome do arquivo onde a exceção originou
    protected $line;                            // Número da linha onde a exceção originou
    private   $trace;                           // Backtrace
    private   $previous;                        // Exceção anterior (se exceção empilhada)

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

    final private function __clone();           // Inibe a clonagem de exceções

    final public  function getMessage();        // Mensagem da exceção
    final public  function getCode();           // Código definido pelo usuário
    final public  function getFile();           // Nome do arquivo onde a exceção originou
    final public  function getLine();           // Número da linha onde a exceção originou
    final public  function getTrace();          // Um array do backtrace()
    final public  function getPrevious();       // Exceção anterior
    final public  function getTraceAsString();  // Backtrace formatado como string

    // Pode ser sobrescrito
    public function __toString();               // String formatada da exceção
}
?>

Se uma classe estender a classe Exception e redefinir o constructor, então é altamente recomendável que também seja chamado o parent::__construct() para garantir que todos os dados estejam corretamente informados. O método __toString() pode ser sobrescrito para fornecer uma representação customizada do objeto quando utilizado como string.

Note:

Exceções não podem ser clonadas. Tentativas de clonar um Exception resultarão em erros E_ERROR fatais.

Example #2 Estendendo a classe Exception

<?php
/**
 * Define uma classe de exceção
 */
class MyException extends Exception
{
    // Redefine a exceção de forma que a mensagem não seja opcional
    public function __construct($message, $code = 0, Throwable $previous = null) {
        // código

        // garante que tudo está corretamente inicializado
        parent::__construct($message, $code, $previous);
    }

    // personaliza a apresentação do objeto como string
    public function __toString() {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }

    public function customFunction() {
        echo "Uma função específica desse tipo de exceção\n";
    }
}


/**
 * Cria uma classe para testar a exceção
 */
class TestException
{
    public $var;

    const THROW_NONE    = 0;
    const THROW_CUSTOM  = 1;
    const THROW_DEFAULT = 2;

    function __construct($avalue = self::THROW_NONE) {

        switch ($avalue) {
            case self::THROW_CUSTOM:
                // lança a exeção customizada
                throw new MyException('1 é um parâmetro inválido', 5);
                break;

            case self::THROW_DEFAULT:
                // throw default one.
                throw new Exception('2 não é um parâmetro permitido', 6);
                break;

            default:
                // Sem exceção, o objeto será criado
                $this->var = $avalue;
                break;
        }
    }
}


// Exemplo 1
try {
    $o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) {      // Entrará aqui ...
    echo "Pegou MyException\n", $e;
    $e->customFunction();
} catch (Exception $e) {        // ... mas não aqui.
    echo "Pegou Exception padrão\n", $e;
}

// Execução continua
var_dump($o); // Null
echo "\n\n";


// Exemplo 2
try {
    $o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) {      // Não entrará aqui ...
    echo "Pegou MyException\n", $e;
    $e->customFunction();
} catch (Exception $e) {        // ... porque entrará aqui.
    echo "Pegou Exception padrão\n", $e;
}

// Execução continua
var_dump($o); // Null
echo "\n\n";


// Exemplo 3
try {
    $o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) {        // Entrará aqui
    echo "Pegou exceção padrão\n", $e;
}

// Execução continua
var_dump($o); // Null
echo "\n\n";


// Exemplo 4
try {
    $o = new TestException();
} catch (Exception $e) {        // Não entrará, sem exceção
    echo "Pegou Exception padrão\n", $e;
}

// Execução continua
var_dump($o); // TestException
echo "\n\n";
?>