catch
Aprenda a usar a palavra-chave "catch" em PHP para capturar e tratar exceções lançadas dentro de blocos "try".
A Palavra-chave catch do PHP
Quando o código dentro de um bloco try encontra uma exceção — um object que sinaliza que algo deu errado — a execução é interrompida e o PHP procura um bloco catch correspondente para tratá-la. A palavra-chave catch define o tipo de exceção que pode tratar e vincula o objeto lançado a uma variável para que você possa inspecioná-lo. Sem um catch, uma exceção não tratada torna-se um erro fatal e interrompe o script.
Esta página explica a sintaxe do catch, como o PHP decide qual bloco executar, como ler detalhes da exceção capturada e os padrões comuns (múltiplos catches, tipos union, relançamento) que você usará em código real.
Sintaxe
Um bloco catch sempre segue um bloco try. Ele declara um tipo de exceção e uma variável que recebe o objeto lançado:
<?php
try {
// Code that may throw an exception
} catch (Exception $e) {
// Runs only if a matching exception is thrown above
echo $e->getMessage();
}O PHP associa um bloco catch quando o objeto lançado é uma instância do tipo declarado. Como toda exceção nativa estende a classe base Exception (e ambas estendem a interface Throwable), catch (Exception $e) captura a maioria das exceções. Capturar Throwable também abrange objetos Error como TypeError e DivisionByZeroError.
Você pode combinar catch com um bloco finally para executar código de limpeza independentemente de uma exceção ter ocorrido ou não.
Um exemplo funcional
A função abaixo lança uma exceção ao ser solicitada a dividir por zero. O bloco catch intercepta essa exceção e a reporta, em vez de deixar o script travar:
<?php
function divide($numerator, $denominator)
{
if ($denominator == 0) {
throw new InvalidArgumentException("Division by zero.");
}
return $numerator / $denominator;
}
try {
echo divide(10, 0);
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
}
// Output: Error: Division by zero.Observe que o script continua executando após o catch — o controle retoma na linha seguinte à estrutura try/catch, em vez de abortar.
Lendo detalhes da exceção capturada
A variável em uma cláusula catch ($e acima) é o próprio objeto exception. Ele expõe métodos que descrevem o que aconteceu:
<?php
try {
throw new RuntimeException("Disk is full", 28);
} catch (RuntimeException $e) {
echo $e->getMessage(); // Disk is full
echo "\n";
echo $e->getCode(); // 28
echo "\n";
echo $e->getLine(); // 4 (line where it was thrown)
}| Método | Retorna |
|---|---|
getMessage() | A mensagem de erro legível por humanos |
getCode() | O código de erro inteiro passado ao construtor |
getFile() | O arquivo em que a exceção foi criada |
getLine() | O número da linha onde foi lançada |
getTrace() | O stack trace como um array |
getPrevious() | A exceção anterior (para exceções encadeadas) |
Capturando múltiplos tipos de exceção
Quando um bloco try pode falhar de diferentes maneiras, liste vários blocos catch. O PHP os testa de cima para baixo e executa o primeiro que corresponder, portanto ordene os tipos mais específicos antes dos gerais:
<?php
try {
// Code that may throw different exceptions
throw new InvalidArgumentException("bad input");
} catch (InvalidArgumentException $e) {
echo "Invalid argument: " . $e->getMessage();
} catch (RuntimeException $e) {
echo "Runtime problem: " . $e->getMessage();
} catch (Exception $e) {
echo "Something else: " . $e->getMessage();
}
// Output: Invalid argument: bad inputSe catch (Exception $e) viesse primeiro, ele absorveria tudo, e os blocos mais específicos abaixo nunca seriam executados.
Union catch (PHP 7.1+)
Quando dois tipos de exceção diferentes precisam de tratamento idêntico, combine-os com um pipe | em vez de duplicar o bloco:
<?php
try {
throw new RuntimeException("connection reset");
} catch (InvalidArgumentException | RuntimeException $e) {
echo "Handled: " . $e->getMessage();
}
// Output: Handled: connection resetCatch sem captura (PHP 8.0+)
Se você não precisar do objeto de exceção, pode omitir a variável completamente:
<?php
try {
throw new Exception("ignored details");
} catch (Exception) {
echo "An error occurred, retrying...";
}
// Output: An error occurred, retrying...Relançamento e encadeamento de exceções
Às vezes um bloco catch deve registrar o problema e então repassá-lo — ou envolver uma exceção de baixo nível em uma mais significativa. Passe a original como terceiro argumento do construtor para preservar a cadeia:
<?php
try {
try {
throw new RuntimeException("low-level failure");
} catch (RuntimeException $e) {
// Wrap and re-throw with context preserved
throw new Exception("High-level operation failed", 0, $e);
}
} catch (Exception $e) {
echo $e->getMessage(); // High-level operation failed
echo "\n";
echo $e->getPrevious()->getMessage(); // low-level failure
}Boas práticas
- Capture o tipo mais específico que você consegue tratar. Um
catch (Throwable $e)genérico pode ocultar bugs ao engolir erros de programação que você pretendia corrigir. - Ordene específicos antes dos gerais. Subclasses específicas devem preceder seus tipos pai.
- Não deixe um
catchvazio. Descartar silenciosamente uma exceção torna as falhas invisíveis; registre-a ao menos. - Lance, não retorne flags de erro. Combine
catchcomthrowpara que os chamadores não possam ignorar falhas acidentalmente. - Use
finallypara limpeza (fechar arquivos, liberar bloqueios) que deve ser executada tanto no caminho de sucesso quanto no de falha.
Tópicos relacionados
- PHP
try— o bloco quecatchprotege - PHP
throw— lançar uma exceção - PHP
finally— código de limpeza garantido - PHP
exception— o objeto de exceção e seus métodos