Em PHP, erros e exceções são mecanismos distintos para lidar com situações inesperadas. Erros são tradicionalmente disparados pelo motor do PHP quando algo grave ocorre, como a falta de um arquivo ou um problema de sintaxe. Exceções, por outro lado, são objetos que podem ser lançados e capturados em blocos try-catch, permitindo um tratamento mais controlado. Nesta aula, vamos focar nos erros: seus tipos, níveis e como configurar o PHP para reportá-los ou exibi-los.

Embora o PHP moderno tenha evoluído para usar exceções em muitas situações (como na PDO ou em bibliotecas modernas), entender os erros tradicionais é fundamental para depurar código legado e para compreender as mensagens de erro que aparecem durante o desenvolvimento.

Tipos de erro

Os erros em PHP são categorizados em três grandes tipos: erros fatais (Error), erros recuperáveis (Warning) e notificações (Notice). Além disso, existem erros de parse (sintaxe) e erros de usuário (gerados manualmente com trigger_error()).

Os erros fatais (E_ERROR) interrompem a execução do script imediatamente. Exemplos incluem: chamar uma função indefinida, estouro de memória ou tempo máximo de execução. Os erros recuperáveis (E_WARNING) não interrompem o script, mas indicam problemas que podem levar a resultados inesperados, como incluir um arquivo inexistente. Já os E_NOTICE são avisos sutis, como usar uma variável não definida. Existe também E_STRICT (sugestões de melhores práticas) e E_DEPRECATED (funções obsoletas).

<?php
// Exemplo de erro fatal (E_ERROR)
// function_nao_existe(); // Isto causaria um erro fatal

// Exemplo de warning (E_WARNING)
include 'arquivo_inexistente.php'; // Gera warning, mas continua

// Exemplo de notice (E_NOTICE)
echo $variavel_nao_definida; // Gera notice
?>

Níveis (E_WARNING, etc.)

Cada tipo de erro possui uma constante pré-definida que representa seu nível. As principais são:

  • E_ERROR (1) – Erro fatal
  • E_WARNING (2) – Aviso
  • E_PARSE (4) – Erro de sintaxe
  • E_NOTICE (8) – Notificação
  • E_CORE_ERROR (16) – Erro fatal do core
  • E_CORE_WARNING (32) – Aviso do core
  • E_COMPILE_ERROR (64) – Erro de compilação
  • E_COMPILE_WARNING (128) – Aviso de compilação
  • E_USER_ERROR (256) – Erro gerado pelo usuário
  • E_USER_WARNING (512) – Aviso gerado pelo usuário
  • E_USER_NOTICE (1024) – Notificação gerada pelo usuário
  • E_STRICT (2048) – Sugestões de codificação
  • E_RECOVERABLE_ERROR (4096) – Erro recuperável
  • E_DEPRECATED (8192) – Função obsoleta
  • E_USER_DEPRECATED (16384) – Função obsoleta gerada pelo usuário
  • E_ALL (30719) – Todos os erros e avisos

Esses valores são máscaras de bits, permitindo combinações. Por exemplo, E_WARNING | E_NOTICE representa ambos os níveis. Na prática, usamos a função error_reporting() para definir quais níveis serão reportados.

<?php
// Exemplo de trigger_error() com nível E_USER_WARNING
trigger_error('Este é um aviso gerado pelo usuário', E_USER_WARNING);
?>

error_reporting

A função error_reporting() define quais níveis de erro serão reportados pelo PHP. Ela aceita uma máscara de bits ou constantes. Por exemplo, error_reporting(E_ALL) faz com que todos os erros sejam reportados, exceto E_STRICT (que foi adicionado separadamente em versões antigas).

No php.ini, a diretiva error_reporting pode ser configurada globalmente. Durante a execução, podemos alterá-la com a função. É uma boa prática em desenvolvimento usar E_ALL para capturar todos os problemas, e em produção usar um nível mais restrito, como E_ALL & ~E_DEPRECATED & ~E_STRICT (todos exceto deprecated e strict).

<?php
// Reportar todos os erros, exceto E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);

// Reportar apenas erros fatais e warnings
error_reporting(E_ERROR | E_WARNING);
?>

display_errors

A diretiva display_errors controla se os erros são exibidos na saída padrão (geralmente o navegador). Em desenvolvimento, costuma-se ativar (On), mas em produção deve ficar desligada (Off) para evitar vazamento de informações sensíveis. Em vez disso, os erros são registrados em log (com log_errors).

No php.ini, display_errors = On ou Off. Também é possível alterar em tempo de execução com ini_set('display_errors', 1) (ou 0 para desligar). É importante notar que erros fatais (E_ERROR) podem não ser afetados por essa configuração se ocorrerem antes da execução do script (como erros de parse).

<?php
// Ativar exibição de erros (apenas para desenvolvimento)
ini_set('display_errors', 1);
error_reporting(E_ALL);

// Desativar em produção
// ini_set('display_errors', 0);
?>

Boas práticas

Em desenvolvimento, mantenha display_errors = On e error_reporting = E_ALL para capturar todos os problemas. Nunca use o operador de supressão de erros (@) indiscriminadamente, pois ele esconde problemas reais. Em produção, desative display_errors e configure log_errors = On para registrar erros em arquivos de log. Utilize também um manipulador de erros personalizado com set_error_handler() para converter erros em exceções (ErrorException) e tratá-los de forma mais elegante.

Referências

Exercícios

  1. Crie um script PHP que gere um warning ao incluir um arquivo inexistente. Observe o comportamento.
  2. ✓ Resposta:
    <?php
    include 'arquivo_inexistente.php';
    echo 'Continua após o warning.';
    ?>
  3. Utilize trigger_error() para gerar um erro do tipo E_USER_NOTICE e exiba uma mensagem.
  4. ✓ Resposta:
    <?php
    trigger_error('Esta é uma notificação gerada pelo usuário', E_USER_NOTICE);
    ?>
  5. Configure o PHP para reportar apenas erros fatais e warnings, ignorando notices.
  6. ✓ Resposta:
    <?php
    error_reporting(E_ERROR | E_WARNING);
    ?>
  7. Escreva um script que desative a exibição de erros e depois tente acessar uma variável indefinida. O que acontece?
  8. ✓ Resposta:
    <?php
    ini_set('display_errors', 0);
    echo $var;
    echo 'Script continua.';
    ?>

    O notice não é exibido, mas o script continua. O erro ainda pode ser registrado em log se log_errors estiver ativo.

  9. Crie um manipulador de erros personalizado que converta warnings em exceções (ErrorException).
  10. ✓ Resposta:
    <?php
    function errorHandler($severity, $message, $file, $line) {
        throw new ErrorException($message, 0, $severity, $file, $line);
    }
    set_error_handler('errorHandler');
    
    try {
        include 'arquivo_inexistente.php';
    } catch (ErrorException $e) {
        echo 'Erro capturado: ' . $e->getMessage();
    }
    ?>