W3docs

Entendendo Exceções no PHP

Em PHP, exceções são usadas para tratar erros inesperados e problemas em tempo de execução. Aprenda a lançar, capturar e criar exceções personalizadas.

Uma exceção é um objeto que representa um erro ou uma condição inesperada que interrompe o fluxo normal do seu programa. Em vez de retornar um código de erro que o chamador pode esquecer de verificar, o código "lança" uma exceção; o ambiente de execução então desfaz a pilha de chamadas até encontrar um bloco catch correspondente. Se nenhum bloco a capturar, o script é encerrado com um erro fatal.

Este capítulo aborda como lançar e capturar exceções, os métodos que toda exceção expõe (getMessage(), getCode(), getLine(), getFile()), o bloco finally, múltiplos blocos catch, classes de exceção personalizadas e a diferença entre Exception e Error.

O que é uma Exceção PHP?

Uma exceção PHP é um objeto que descende da classe embutida Exception (ou, de forma mais ampla, da interface Throwable). Quando algo dá errado — um arquivo ausente, um argumento inválido, uma conexão de banco de dados com falha — você cria um desses objetos e o throw (lança). Lançar imediatamente interrompe o caminho de execução atual e passa o controle para o manipulador mais próximo.

Use uma exceção quando uma função não puder continuar de forma significativa e o chamador for o lugar certo para decidir o que fazer a seguir. Não as use para fluxo de controle comum (uma busca normal de "usuário não encontrado" é melhor expressa com um valor de retorno).

Lançando uma Exceção

A palavra-chave throw lança uma exceção, seguida de uma nova instância de uma classe de exceção. O construtor aceita uma mensagem opcional, um código inteiro e uma exceção anterior (para encadeamento):

<?php

function divide(int $a, int $b): float
{
    if ($b === 0) {
        throw new InvalidArgumentException('Division by zero is not allowed.');
    }
    return $a / $b;
}

try {
    echo divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo 'Error: ' . $e->getMessage();
}
?>

Saída:

Error: Division by zero is not allowed.

O código dentro do try é executado normalmente até que throw seja disparado. A partir desse ponto, o restante do bloco try é ignorado e o bloco catch correspondente é executado.

Tratando Exceções com try / catch

Você envolve o código que pode falhar em um bloco try e se recupera da falha em um bloco catch. A variável no catch (aqui $e) contém o objeto de exceção, que expõe vários métodos somente leitura:

MétodoRetorna
getMessage()A mensagem legível por humanos
getCode()O código inteiro passado ao construtor
getLine()A linha onde a exceção foi lançada
getFile()O arquivo onde foi lançada
getPrevious()A exceção "anterior" encadeada, se houver
getTraceAsString()O rastreamento de pilha como string
<?php

try {
    throw new Exception('Something failed', 42);
} catch (Exception $e) {
    echo 'Message: ' . $e->getMessage() . PHP_EOL;
    echo 'Code: ' . $e->getCode() . PHP_EOL;
}
?>

Saída:

Message: Something failed
Code: 42

Capturando Múltiplos Tipos de Exceção

Um único bloco try pode ter vários blocos catch. O PHP os verifica de cima para baixo e executa o primeiro cujo tipo corresponda. Desde o PHP 7.1, você também pode capturar vários tipos não relacionados em um único bloco usando o operador pipe (|):

<?php

try {
    throw new RuntimeException('Network is down');
} catch (InvalidArgumentException $e) {
    echo 'Bad argument: ' . $e->getMessage();
} catch (RuntimeException | LogicException $e) {
    echo 'Runtime/logic problem: ' . $e->getMessage();
}
?>

Saída:

Runtime/logic problem: Network is down

A ordem importa: liste os tipos de exceção mais específicos antes de suas classes pai, caso contrário o catch mais abrangente captura tudo primeiro.

O Bloco finally

O bloco finally é opcional, mas útil. Seu código sempre é executado — independentemente de uma exceção ter sido lançada ou não, e mesmo que o bloco try ou catch execute um return. Isso o torna o lugar certo para limpeza, como fechar um identificador de arquivo ou liberar um bloqueio:

<?php

try {
    echo 'Open resource' . PHP_EOL;
    throw new Exception('Boom');
} catch (Exception $e) {
    echo 'Caught: ' . $e->getMessage() . PHP_EOL;
} finally {
    echo 'Cleanup always runs' . PHP_EOL;
}
?>

Saída:

Open resource
Caught: Boom
Cleanup always runs

Classes de Exceção Personalizadas

Além dos tipos embutidos, você pode definir suas próprias classes de exceção estendendo Exception. Uma classe personalizada permite carregar dados extras (como um valor com falha) e permite que os chamadores capturem seu tipo de erro específico sem capturar acidentalmente outros não relacionados:

<?php

class InsufficientFundsException extends Exception
{
    private float $shortfall;

    public function __construct(float $shortfall)
    {
        $this->shortfall = $shortfall;
        parent::__construct("Short by $shortfall");
    }

    public function getShortfall(): float
    {
        return $this->shortfall;
    }
}

try {
    throw new InsufficientFundsException(25.5);
} catch (InsufficientFundsException $e) {
    echo $e->getMessage() . PHP_EOL;
    echo 'Need ' . $e->getShortfall() . ' more.';
}
?>

Saída:

Short by 25.5
Need 25.5 more.

O PHP também inclui uma família de exceções SPL prontas para uso — InvalidArgumentException, RuntimeException, LengthException, entre outras — portanto, muitas vezes você não precisa criar as suas próprias.

Exception vs. Error

Desde o PHP 7, falhas internas do motor (como um erro de tipo ou chamada de método indefinido) são lançadas como objetos Error, não como objetos Exception. Ambos implementam a interface Throwable. Um simples catch (Exception $e) não capturará um Error. Para tratar ambos, capture a interface:

<?php

try {
    $result = 10 % 0; // throws a DivisionByZeroError
} catch (Throwable $e) {
    echo get_class($e) . ': ' . $e->getMessage();
}
?>

Saída:

DivisionByZeroError: Modulo by zero

Como regra, reserve Exception para problemas dos quais sua aplicação pode se recuperar, e deixe Error representar bugs que você deve corrigir em vez de capturar.

Tópicos Relacionados

Conclusão

Exceções oferecem ao PHP uma maneira estruturada de lidar com falhas: uma função throw (lança) quando não pode continuar, e o chamador catch (captura) para recuperar, registrar ou relançar. Combine try, catch e finally para separar o caminho feliz do tratamento de erros e da limpeza, use classes personalizadas para modelar as falhas do seu domínio, e lembre-se de que problemas no nível do motor chegam como Error (capturáveis via Throwable). Praticar esses padrões em seus próprios projetos tornará seu código muito mais robusto.

Prática

Prática
O que é verdadeiro sobre Exceções PHP de acordo com as informações na URL fornecida?
O que é verdadeiro sobre Exceções PHP de acordo com as informações na URL fornecida?
Was this page helpful?