set_error_handler()
Aprenda a usar set_error_handler() no PHP para interceptar erros não fatais, registrá-los e convertê-los em exceções.
O comportamento padrão do PHP em um erro não fatal é imprimir uma mensagem na saída (ou registrá-la) e continuar a execução. Isso raramente é o que você deseja em produção: a mensagem bruta pode vazar caminhos de arquivos para visitantes, e você não tem um local centralizado para registrar, formatar ou converter erros. A função set_error_handler() resolve isso roteando os erros internos do PHP por uma função que você controla.
Este capítulo explica o que set_error_handler() faz, a assinatura exata do callback que o PHP espera, quais erros ela pode e não pode interceptar, e como usá-la para um registro limpo.
O que set_error_handler() faz
set_error_handler() registra um callback que o PHP invoca em vez de seu manipulador de erros interno sempre que um erro correspondente (não fatal) é levantado. Seu callback decide o que acontece em seguida — registrá-lo, exibir uma mensagem amigável, lançar uma exceção ou ignorá-lo silenciosamente.
Ela não impede que os erros sejam levantados; apenas muda como eles são tratados. O PHP ainda respeita error_reporting ao decidir se deve chamar seu manipulador.
Sintaxe
set_error_handler(
callable|null $callback,
int $error_levels = E_ALL
): callable|false| Parâmetro | Descrição |
|---|---|
$callback | A função que o PHP chama quando um erro ocorre. Passe null para restaurar o manipulador interno do PHP. |
$error_levels | Uma máscara de bits dos níveis de erro que seu manipulador deve receber (ex.: E_WARNING | E_NOTICE). O padrão é E_ALL. |
Valor de retorno: o manipulador anteriormente registrado (um callable), ou null se não havia nenhum. Retorna false apenas quando o callback é inválido.
A assinatura do callback
O PHP chama seu manipulador com até cinco argumentos. Os primeiros quatro são os que você mais usará:
function handler(
int $errno, // the error level constant, e.g. E_WARNING
string $errstr, // the error message
string $errfile = "", // file where the error occurred
int $errline = 0 // line number
): bool {
// ...
}Se seu manipulador retornar false, o PHP continua com seu tratamento de erros interno normal em seguida. Retornar true (ou nada) informa ao PHP que o erro foi totalmente tratado e suprime o comportamento padrão.
Quais erros ele pode capturar
set_error_handler() intercepta os níveis de erro capturáveis pelo usuário — avisos, notificações, depreciações e a família E_USER_* levantada por trigger_error():
| Capturável | Não capturável (fatal) |
|---|---|
E_WARNING, E_NOTICE, E_DEPRECATED | E_ERROR |
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE | E_PARSE |
E_RECOVERABLE_ERROR, E_STRICT | E_CORE_ERROR, E_COMPILE_ERROR |
Nota: Erros fatais como
E_ERROReE_PARSEignoram seu manipulador e encerram o script. Para capturar esses, combine seu manipulador comset_exception_handler()e uma função de encerramento. Exceções não capturadas também não são roteadas aqui — elas têm seu próprio manipulador.
Um manipulador básico
Defina uma função com a assinatura esperada e registre-a. Aqui uma chamada trigger_error() simula um aviso para que você possa ver o manipulador em execução:
<?php
function customErrorHandler($errno, $errstr, $errfile, $errline)
{
echo "Handled error [$errno]: $errstr in $errfile on line $errline\n";
return true; // we consider the error fully handled
}
set_error_handler("customErrorHandler");
trigger_error("This is a test warning", E_USER_WARNING);
// Restore PHP's default error handling
restore_error_handler();Saída:
Handled error [512]: This is a test warning in ... on line 11512 é o valor numérico de E_USER_WARNING. Após restore_error_handler(), os erros voltam ao comportamento padrão do PHP.
Convertendo erros em exceções
Um padrão comum em produção é transformar avisos e notificações em exceções para que fluam pela lógica normal de try/catch. Isso permite que você trate um file_get_contents() com falha (que emite apenas um aviso) com try/catch:
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
// Respect the @ operator and error_reporting settings.
if (!(error_reporting() & $errno)) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
$data = file_get_contents("/no/such/file");
} catch (ErrorException $e) {
echo "Caught: " . $e->getMessage() . "\n";
}Saída:
Caught: file_get_contents(/no/such/file): Failed to open stream: No such file or directoryRegistrando em vez de exibir
Mapear a constante de nível para um rótulo legível mantém os logs fáceis de ler. Use error_log() para gravar no destino de log configurado:
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
$levels = [
E_WARNING => "WARNING",
E_NOTICE => "NOTICE",
E_DEPRECATED => "DEPRECATED",
E_USER_WARNING => "USER_WARNING",
];
$label = $levels[$errno] ?? "UNKNOWN($errno)";
$line = "[$label] $errstr in $errfile:$errline";
error_log($line); // goes to your log, not the page
echo $line . "\n"; // shown here only to demonstrate the output
return true;
});
trigger_error("Disk space low", E_USER_WARNING);Saída:
[USER_WARNING] Disk space low in ... :15Armadilhas comuns
- O operador
@. Quando um erro é silenciado com@,error_reporting()retorna0dentro do seu manipulador. Verifiqueerror_reporting() & $errnose quiser honrar@, como mostrado acima. - Erros fatais ainda escapam. Independentemente do segundo argumento,
E_ERRORe erros de análise nunca são entregues ao seu manipulador. - É global. Um manipulador registrado afeta toda a requisição. Bibliotecas que definem seu próprio manipulador podem sobrescrever o seu, portanto restaure os manipuladores quando terminar.
- Não use
echoem produção. Exibir mensagens brutas vaza caminhos e ajuda atacantes — registre-as e mostre uma página genérica.
Funções relacionadas
restore_error_handler()— reverte para o manipulador anterior.trigger_error()— levanta seus próprios errosE_USER_*.error_reporting()— controla quais níveis estão ativos.set_exception_handler()— captura exceções não tratadas.
Conclusão
set_error_handler() oferece um único lugar para interceptar os erros não fatais do PHP e aplicar sua própria lógica — registrá-los, convertê-los em exceções ou ocultá-los dos usuários. Combine-a com um manipulador de exceções e registro adequado para tratamento de erros de nível produção. Lembre-se de seu único limite rígido: erros fatais e de análise a ignoram completamente.