Forum und email

Exceções

PHP 5 tem um modelo de exceção similar ao de outras linguagens de programação. Uma exceção pode ser disparada (thrown), ou pega (caught ou "catched") no PHP. Código pode ser rodeado em um block try, para facilitar a captura de exceções em potencial. Cada bloco try, deve ter pelo menos um bloco catch correspondente. Vários blocos catch pode ser usado para pegar diferentes classes de exceções. A execução normal (quando nenhuma exceção é disparada dentro de um bloco try ou quando um catch compatível com a classe da exceção disparada não estiver presente) continuará após o último bloco catch definido na seqüência. Exceções podem ser disparadas (ou re-disparadas) dentro de um bloco catch.

Quando uma exceção é disparada, código logo após à instrução não será executada, e o PHP tentará achar o primeiro bloco catch correspondente à exceção disparada. Se uma exceção não for pega, um Erro Fatal do PHP será lançado com uma mensagem "Uncaught Exception ...", a não ser que um tratador tenha sido definido com set_exception_handler().

Example#1 Disparando uma Exceção

<?php
function inverse($x) {
    if (!
$x) {
        throw new 
Exception('Division by zero.');
    }
    else return 
1/$x;
}

try {
    echo 
inverse(5) . "\n";
    echo 
inverse(0) . "\n";
} catch (
Exception $e) {
  echo 
"Exceção pega: ",  $e->getMessage(), "\n";
}

// continua a execução
echo 'Hello World';
?>

O exemplo acima irá imprimir:

0.2
Exceção pega: Division by zero.
Hello World

Herdando 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#2 A classe nativa Exception

<?php
class Exception {

  protected 
$message 'Unknown exception'// Mensagem da exceção
  
protected $code 0;                      // Código da exceção definido pelo usuário
  
protected $file;                          // Arquivo gerador da exceção
  
protected $line;                          // Linha geradora da exceção

  
function __construct(string $message=NULLint code=0);

  final function 
getMessage();              // Mensagem da exceção
  
final function getCode();                 // Código da exceção
  
final function getFile();                 // Arquivo gerador
  
final function getTrace();                // um array com o backtrace()
  
final function getTraceAsString();        // String formatada do trace

  /* Sobrecarregável */
  
function _toString();                     // String formatada para ser mostrada

}
?>

Se uma classe herda da classe Exception e redefine o construtor, é altamente recomendado que o mesmo chame parent::__construct() para garantir que todas as informações disponíveis sejam devidamente atribuídas. O método __toString() pode ser sobrecarregado para permitir uma saída personalizada quando o objeto é apresentado como string.

Example#3 Herdando a classe Exception

<?php

class MyException extends Exception {

  
/* Redefine a exceção para que a mensagem não seja opcional */
  
public function __construct($message$code 0) {

    
// coisas personalizadas que você queira fazer
    // ...

    /* Garante que tudo é atribuído corretamente */
    
parent::__construct($message$code);
  }

  
/* Representação do objeto personalizada no formato string */
  
public function __toString() {
    return 
__CLASS__ ": [{$this->code}]: {$this->message}\n";
  }

  public function 
customFunction() {
    echo 
"Uma função personalizada para esse 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:
        
// dispara exceção personalizada
        
throw new MyException('1 é um parâmetro inválido'5);
        break;

      case 
self::THROW_DEFAULT:
        
// dispara a padrão
        
throw new Exception('2 não é permitido como parâmetro'6);

        break;

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

    }

  }

}

// Exemplo 1
try {
  
$o = new TestException(TestException::THROW_CUSTOM);
}
catch (
MyException $e) {            /* Será pega */
  
echo "Pegou minha exceção\n"$e;
  
$e->customFunction();
}
catch (
Exception $e) {              /* Ignorado */
  
echo "Pegou Exceção Padrão\n"$e;
}
var_dump($o);                       /* continua execução */
echo "\n\n";


// Exemplo 2
try {
  
$o = new TestException(TestException::THROW_DEFAULT);
}
catch (
MyException $e) {            /* Tipos não batem */
  
echo "Pegou minha exceção\n"$e;
  
$e->customFunction();
}
catch (
Exception $e) {              /* Será pega */
  
echo "Pegou Exceção Padrão\n"$e;
}
var_dump($o);                       /* continua execução */
echo "\n\n";


// Exemplo 3
try {
  
$o = new TestException(TestException::THROW_CUSTOM);
}
catch (
Exception $e) {              /* Será pega */
  
echo "Default Exception caught\n"$e;
}
var_dump($o);                       /* continua execução */
echo "\n\n";


// Exemplo 4
try {
  
$o = new TestException();
}
catch (
Exception $e) {              /* Ignorada, nenhuma exceção */
  
echo "Default Exception caught\n"$e;
}
var_dump($o);                       /* continua execução */
echo "\n\n";