W3docs

throw

Em PHP, a palavra-chave "throw" é usada para lançar uma exceção. Aprenda a sintaxe, exemplos e boas práticas neste artigo.

A Palavra-chave throw do PHP

A palavra-chave throw interrompe a execução normal no ponto em que é executada e lança uma exceção — um objeto que sinaliza que algo deu errado. O controle salta imediatamente para fora da função atual e sobe pela pilha de chamadas até encontrar um bloco catch correspondente. Se nenhum catch corresponder, o PHP encerra o script com um erro fatal.

Esta página aborda a sintaxe de throw, quando usá-lo em vez de retornar um valor de erro, como lançar exceções embutidas e personalizadas, relançamento e encadeamento, e o recurso do PHP 8 que permite usar throw como expressão. Para uma visão mais ampla, consulte Exceções em PHP e o fluxo try/catch/finally.

Sintaxe

throw new Exception("Error message here");

throw deve receber um valor que seja uma instância de Throwable — na prática, uma Exception (ou uma de suas subclasses) ou um Error. A string passada ao construtor se torna a mensagem da exceção, que você lê posteriormente com getMessage().

Como uma exceção lançada desfaz a pilha, qualquer código após throw no mesmo bloco nunca é executado:

throw new Exception("stop here");
echo "this line is unreachable"; // never executes

Por que usar throw em vez de retornar um erro?

Retornar um valor especial (como false ou -1) para sinalizar falha obriga cada chamador a lembrar de verificá-lo, e o significado do valor é fácil de perder. throw torna a falha impossível de ignorar: a exceção se propaga automaticamente até que algo a trate, e carrega uma mensagem, um código, um rastreamento de pilha, além do arquivo e linha onde ocorreu.

Use throw para condições excepcionais das quais a função atual não consegue se recuperar de forma sensata — argumentos inválidos, uma conexão de banco de dados com falha, um arquivo obrigatório ausente — e deixe um chamador em nível superior decidir o que fazer.

Um exemplo básico

Aqui, uma função divide() lança uma exceção ao ser solicitada a dividir por zero, e o chamador a captura:

<?php

function divide(int $numerator, int $denominator): float
{
    if ($denominator === 0) {
        throw new InvalidArgumentException("Cannot divide by zero.");
    }
    return $numerator / $denominator;
}

try {
    echo divide(10, 2), PHP_EOL; // 5
    echo divide(10, 0), PHP_EOL; // throws before printing
} catch (InvalidArgumentException $e) {
    echo "Caught: " . $e->getMessage() . PHP_EOL;
}

Saída:

5
Caught: Cannot divide by zero.

A primeira chamada é bem-sucedida e imprime 5. A segunda chamada lança uma exceção, portanto seu echo nunca é executado e o controle vai direto para o bloco catch.

Lançando uma exceção personalizada

Estender Exception permite dar a cada tipo de erro seu próprio nome, para que os chamadores possam capturar exatamente as falhas que lhes interessam e ignorar o resto:

<?php

class InsufficientFundsException extends Exception {}

function withdraw(float $balance, float $amount): float
{
    if ($amount > $balance) {
        throw new InsufficientFundsException(
            "Cannot withdraw $amount; balance is only $balance."
        );
    }
    return $balance - $amount;
}

try {
    echo withdraw(100, 250), PHP_EOL;
} catch (InsufficientFundsException $e) {
    echo "Declined: " . $e->getMessage() . PHP_EOL;
}

Saída:

Declined: Cannot withdraw 250; balance is only 100.

Consulte Classes de exceção personalizadas para saber mais sobre como estender Exception.

Mensagem, código e exceção anterior

O construtor de Exception aceita três argumentos — message, code e uma exceção previous. O terceiro permite encapsular um erro de baixo nível em um mais significativo sem perder a causa original (isso é chamado de encadeamento de exceções):

<?php

try {
    try {
        throw new RuntimeException("Disk read failed", 13);
    } catch (RuntimeException $low) {
        // Re-throw a higher-level exception, keeping the original as the cause.
        throw new Exception("Could not load config", 0, $low);
    }
} catch (Exception $e) {
    echo $e->getMessage() . PHP_EOL;                 // Could not load config
    echo "Caused by: " . $e->getPrevious()->getMessage() . PHP_EOL; // Disk read failed
    echo "Original code: " . $e->getPrevious()->getCode() . PHP_EOL; // 13
}

Saída:

Could not load config
Caused by: Disk read failed
Original code: 13

Relançando em um bloco catch

Você não precisa tratar completamente uma exceção onde a captura. Um bloco catch pode fazer algum trabalho (registrá-la, adicionar contexto) e então throw novamente para deixar um tratador externo concluir o trabalho:

<?php

function loadUser(int $id): array
{
    try {
        throw new RuntimeException("Database is down");
    } catch (RuntimeException $e) {
        error_log("loadUser($id) failed: " . $e->getMessage());
        throw $e; // pass it on
    }
}

try {
    loadUser(7);
} catch (RuntimeException $e) {
    echo "Handled at top level: " . $e->getMessage() . PHP_EOL;
}

Saída:

Handled at top level: Database is down

throw como expressão (PHP 8+)

Desde o PHP 8.0, throw é uma expressão, não apenas uma instrução, portanto você pode usá-lo em lugares que esperam um valor — como os operadores ?: e ?? ou uma arrow function:

<?php

function getConfig(array $config, string $key): string
{
    // Throw inline when the key is missing.
    return $config[$key] ?? throw new InvalidArgumentException("Missing key: $key");
}

echo getConfig(['env' => 'prod'], 'env'), PHP_EOL; // prod

try {
    getConfig(['env' => 'prod'], 'region');
} catch (InvalidArgumentException $e) {
    echo $e->getMessage() . PHP_EOL;
}

Saída:

prod
Missing key: region

Erros comuns

  • Lançar sem um try/catch em nenhum lugar acima na pilha. Uma exceção não capturada se torna um erro fatal e para o script. Sempre capture-a em algum lugar, ou registre um fallback com set_exception_handler().
  • Lançar uma string ou array. throw requer um objeto implementando Throwable; throw "oops"; é um erro de sintaxe.
  • Engolir exceções silenciosamente. Um bloco catch vazio oculta bugs. No mínimo, registre a mensagem, ou relance.
  • Usar exceções para fluxo de controle comum. Lançar em cada ramificação esperada (por exemplo, "usuário não encontrado" durante uma busca de rotina) é lento e confuso — reserve para casos genuinamente excepcionais.

Resumo

  • throw lança um Throwable e imediatamente desfaz a pilha até o catch correspondente mais próximo.
  • Prefira-o a valores de retorno mágicos para que falhas não possam ser ignoradas silenciosamente.
  • Crie subclasses de Exception para criar tipos de erro nomeados; passe uma exceção previous para encadear causas.
  • Capture, adicione contexto e throw novamente para deixar um tratador externo decidir.
  • No PHP 8+, throw funciona como expressão dentro de ??, ?: e arrow functions.

Continue com o bloco try, o bloco catch e finally para ver o ciclo completo de tratamento de exceções.

Prática

Prática
O que o comando 'throw' faz em PHP?
O que o comando 'throw' faz em PHP?
Was this page helpful?