W3docs

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étodoRetorna
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 input

Se 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 reset

Catch 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 catch vazio. Descartar silenciosamente uma exceção torna as falhas invisíveis; registre-a ao menos.
  • Lance, não retorne flags de erro. Combine catch com throw para que os chamadores não possam ignorar falhas acidentalmente.
  • Use finally para limpeza (fechar arquivos, liberar bloqueios) que deve ser executada tanto no caminho de sucesso quanto no de falha.

Tópicos relacionados

Prática

Prática
O que acontece quando uma exceção é lançada e não capturada em PHP?
O que acontece quando uma exceção é lançada e não capturada em PHP?
Was this page helpful?