aprender PHP logo

Lançar (throw) e capturar (try / catch) exceções em PHP é parte essencial da sua programação orientada a objetos. Com elas você pode criar um “erro” (uma exceção) que deverá ser capturado quando a classe ou função for executada.

Utilizamos throw para lançar uma nova exceção da seguinte maneira:

<?php
function mensagem ( $mensagem = null ) {
    // Verifica se a mensagem NÃO foi enviada
    if ( ! $mensagem ) {
        // Lança uma nova exceção
        throw new Exception('Mensagem não enviada!');
    }
    
    // Exibe a mensagem
    echo $mensagem;
}
?>

No código acima, criei uma função que exibirá uma mensagem que deverá (obrigatoriamente) ser enviada para o parâmetro $mensagem da mesma. Se a mensagem não for enviada pelo desenvolvedor, lanço uma exceção detalhando o que ocorreu.

Quando throw é encontrado pelo interpretador do PHP, o código irá ler o que ele diz e não executará o restante daquela função, ou seja, eu não preciso verificar novamente se o parâmetro foi enviado para continuar escrevendo o restante dos códigos daquela função.

Um ponto importante a ser ressaltado, é que agora você não deve executar a função diretamente, como era de costume.

// Executa a função sem o parâmetro mensagem
mensagem();

Isso irá lançar o seguinte erro fatal:

Fatal error: Uncaught exception ‘Exception’ with message ‘Mensagem não enviada!’ in D:hd_antigoProgramasEasyPHPdatalocalwebindex.php:6 Stack trace: #0 D:hd_antigoProgramasEasyPHPdatalocalwebindex.php(14): mensagem() #1 {main} thrown in D:hd_antigoProgramasEasyPHPdatalocalwebindex.php on line 6

O que aconteceu no erro acima foi que o interpretador do PHP encontrou uma exceção lançada com o bloco throw na linha 6 do arquivo index.php, mas não encontrou uma maneira de capturar essa exceção.

Capturar uma exceção significa utilizar o bloco try para tentar executar a função, e pelo menos um bloco catch para capturar e manipular o erro.

A maneira mais simples para resolver o problema acima seria:

// Executa o código
try {
    // Executa a função sem o parâmetro mensagem
    mensagem();
} catch( Exception $e ) {
    // Exibe a exceção (erro)
    echo $e->getMessage();
}

O bloco try/catch em PHP funcionam de maneira similar às estruturas condicionais em PHP, porém, ao invés de imaginar “Se / se não”, imagine “Tente / capture”.

Try sempre será executado enquanto um throw não for encontrado. Se throw for encontrado pelo interpretador do PHP, o código daquela função ou método imediatamente para de ser executado e os comandos do bloco catch serão executados.

Veja mais um exemplo, mas agora com classes PHP:

<?php
// Cria uma classe
class Mensagem
{
    // Um método
    public function exibe( $mensagem = false ) {
        // Verifica se a mensagem NÃO (!) foi enviada como parâmetro
        if ( ! $mensagem ) {
            throw new Exception('Envie a mensagem em $mensagem!');
        }
        
        // Exibe a mensagem
        echo $mensagem;
    }
}

// Executa o código
try {
    // Cria uma instância da classe
    $mensagem = new Mensagem();
    
    // Executa o método exibe
    $mensagem->exibe();
} catch( Exception $e ) {
    // Exibe a exceção (erro)
    echo $e->getMessage();
}
?>

No código acima, o bloco catch será executado, já que tentamos executar o método “exibe” sem enviar o parâmetro $mensagem. Consequentemente, ao invés de exibir qualquer coisa na tela, o usuário verá apenas:

Envie a mensagem em $mensagem!

Para que o bloco try seja executado, deveríamos executar o método “exibe” da seguinte maneira:

$mensagem->exibe("Oi, agora tenho uma mensagem!");

E resolveríamos o problema do parâmetro $mensagem.

Você também pode estender a classe “Exception” para criar suas próprias exceções da seguinte maneira:

<?php
// Nova exceção
class MinhaExcecao Extends Exception { }

Nesse caso nosso código mudaria um pouco, veja:

<?php
// Nova exceção
class MinhaExcecao Extends Exception { }

// Cria uma classe
class Mensagem
{
    // Um método
    public function exibe( $mensagem = false ) {
        // Verifica se a mensagem NÃO (!) foi enviada como parâmetro
        if ( ! $mensagem ) {
            // Lança a nova excessão
            throw new MinhaExcecao('Envie a mensagem em $mensagem!');
        }
        
        // Exibe a mensagem
        echo $mensagem;
    }
}

// Executa o código
try {
    // Cria uma instância da classe
    $mensagem = new Mensagem();
    
    // Executa o método exibe
    $mensagem->exibe();
} catch( MinhaExcecao $e ) {
    // Exibe a exceção (erro)
    echo $e->getMessage();
}
?>

No trecho de código acima, ao invés de lançar e capturar exceções na classe “Exception”, faço o mesmo na minha nova classe de exceções “MinhaExcecao”.

Uma parte importante da classe “Exception” no PHP, é que ela tem vários métodos interessantes, são eles:

  • getMessage () – A mensagem de erro
  • getCode () – O código de erro
  • getFile () – O arquivo de erro
  • getLine () – A linha do erro
  • getTrace () – Informações de contexto do erro
  • getTraceAsString () – Mesmo informação anterior, só que com string

Com isso podemos gerar erros mais precisos, veja:

// Executa o código
try {
    // Cria uma instância da classe
    $mensagem = new Mensagem();
    
    // Executa o método exibe
    $mensagem->exibe();
} catch( MinhaExcecao $e ) {
    echo '<b>Erro: </b>';
    echo $e->getMessage() . '<br>';
    echo ' <b>Na linha: </b>';
    echo $e->getLine() . '<br>';
    echo ' <b>Arquivo: </b>';
    echo $e->getFile() . '<br>';
}

O trecho de código acima deverá lançar um erro da seguinte maneira:

Erro: Envie a mensagem em $mensagem!
Na linha: 13
Arquivo: D:hd_antigoProgramasEasyPHPdatalocalwebindex.php

Bem mais detalhado.

Concluindo

Exceções trazem uma nova maneira de trabalhar com o PHP Orientado a Objetos, deixando o PHP mais próximo de linguagens como Java ou C. Utilize com sabedoria.

Caso queira tirar alguma dúvida, basta deixar um comentário.