Amigos, hoje vamos falar sobre algo que enlouquece qualquer um que já teve que fuçar em código PHP alheio. Você abre um site e não há nada. Uma tela em branco. Nenhum erro, nenhuma pista do que deu errado.
Isso soa familiar?
Este é o caso clássico de um erro fatal do PHP que simplesmente mata o script e desaparece sem se despedir. Hoje, vamos aprender como fazer o PHP falar, ativar os logs e encontrar aqueles erros fatais que se escondem atrás da "tela branca da morte".
Por que o PHP fica em silêncio: um pouco de teoria
Primeiro, vamos entender como o PHP lida com erros em geral. Não é apenas "erro -> log". Existe toda uma hierarquia.
No PHP 7+, tudo que pode dar errado implementa a interface Throwable. Ela tem dois herdeiros principais: - Error — erros internos do PHP (fatais, de parse, de tipo) - Exception — exceções que podem ser capturadas com try-catch
Os erros fatais (E_ERROR, E_PARSE, E_CORE_ERROR) são o pior pesadelo de qualquer desenvolvedor. Eles matam o script instantaneamente, e os manipuladores padrão via set_error_handler() não os capturam . A única maneira de interceptar um erro fatal é usar register_shutdown_function().
Mas vamos passo a passo. Primeiro, precisamos ativar o log para que os erros sejam realmente escritos em algum lugar.
Passo 1: Ativando o log via php.ini
A maneira mais correta de configurar os logs é editar o arquivo de configuração do PHP. Onde ele está localizado depende do seu sistema :
| Sistema | Caminho para php.ini |
|---------|----------------------|
| Ubuntu/Debian (Apache) | /etc/php/7.x/apache2/php.ini |
| Ubuntu/Debian (CLI) | /etc/php/7.x/cli/php.ini |
| Ubuntu/Debian (PHP-FPM) | /etc/php/7.x/fpm/php.ini |
| CentOS/RHEL | /etc/php.ini ou /etc/php.d/ |
| Windows (XAMPP) | C:\xampp\php\php.ini |
| Windows (WAMP) | C:\wamp\bin\php\phpX.X.X\php.ini |
Neste arquivo, estamos interessados nas seguintes diretivas :
```ini ; Ativar a escrita de erros em um arquivo de log (obrigatório!) log_errors = On
; Especificar o caminho para o arquivo de log error_log = /var/log/php_errors.log
; Desativar a exibição de erros na tela (para produção!) display_errors = Off
; Para desenvolvimento, você pode ativar isso, mas desative depois display_startup_errors = Off
; Nível de relatório de erros — todos os erros error_reporting = E_ALL ```
Importante: A interface de linha de comando (CLI) usa seu próprio php.ini, e os logs podem ser escritos em um local diferente . Se você estiver testando um script no console, verifique separadamente.
Após fazer as alterações, você precisa reiniciar o servidor web :
bash
sudo systemctl restart apache2 # para Apache
sudo systemctl restart php7.4-fpm # para PHP-FPM
O que essas configurações significam
- log_errors = On — ativa a escrita de erros em um arquivo. Sem isso, o PHP ficará mudo como um túmulo .
- error_log — o caminho para o arquivo onde tudo será escrito. É crucial que o usuário do servidor web (geralmente
www-dataouapache) tenha permissões de escrita para este arquivo e seu diretório . - display_errors = Off — desative isso em produção para não expor detalhes aos usuários .
- error_reporting = E_ALL — registrar todos os tipos de erros. Para produção, você pode limitar isso, mas para depuração é melhor ver tudo.
Passo 2: Alternativa: Ativando o log diretamente no código
Se você não tem acesso ao php.ini (por exemplo, em hospedagem compartilhada), pode tentar ativar o log diretamente no seu script usando a função ini_set().
Insira isso no início do arquivo problemático:
```php
/dev/null ``` Ou crie um arquivo PHP com `phpinfo();` e procure pela seção **error_log**. ## Passo 4: Lendo os logs: ferramentas e técnicas Uma vez que os logs estão sendo escritos, você precisa saber como visualizá-los e filtrá-los rapidamente. ### tail — Vendo os últimos eventos ```bash # Últimas 50 linhas tail -n 50 /var/log/php_errors.log # Seguir em tempo real (como docker logs -f) tail -f /var/log/php_errors.log ``` ### grep — Procurando erros específicos ```bash # Apenas erros fatais grep "Fatal error" /var/log/php_errors.log # Erros de parse (erros de sintaxe) grep "Parse error" /var/log/php_errors.log # Ignorar maiúsculas/minúsculas grep -i "warning" /var/log/php_errors.log ``` ### less — Visualização conveniente com navegação ```bash less /var/log/php_errors.log ``` Dentro do less, você pode pressionar `/` e digitar uma palavra para pesquisar, `n` para o próximo resultado, `N` para o anterior. ### Combinações — Um pipeline poderoso ```bash # Mostrar as últimas 100 linhas e procurar erros tail -n 100 /var/log/php_errors.log | grep -i fatal # Seguir e filtrar em tempo real tail -f /var/log/php_errors.log | grep --line-buffered "error" # Contar erros por tipo grep -o "PHP [A-Za-z]* error" /var/log/php_errors.log | sort | uniq -c ``` ## Passo 5: Decifrando os erros: o que é cada coisa Uma entrada de log típica se parece com isto : ``` [2026-03-04 14:35:22 UTC] PHP Fatal error: Uncaught Error: Call to undefined function foo() in /var/www/html/index.php on line 10 ``` Vamos analisá-la: - **Data e Hora** — quando aconteceu - **PHP Fatal error** — o nível do erro - **Uncaught Error: Call to undefined function foo()** — a mensagem - **/var/www/html/index.php:10** — o arquivo e o número da linha Principais níveis de erro : | Nível | Significado | Exemplo | |-------|-------------|---------| | **E_ERROR** / **Fatal error** | Erro fatal, o script morre | Chamar uma função inexistente, memória insuficiente | | **E_WARNING** / **Warning** | Aviso, mas o script continua | `include` de um arquivo inexistente | | **E_PARSE** / **Parse error** | Erro de sintaxe, o script não executa | Ponto e vírgula faltando | | **E_NOTICE** / **Notice** | Notificação, geralmente não crítica | Acessar uma variável não definida | | **E_DEPRECATED** | Construção obsoleta | Usar `mysql_connect()` | ## Passo 6: Capturando erros fatais (A parte interessante) Erros fatais são aqueles que não podem ser capturados pelo `set_error_handler()` padrão. Eles matam o script instantaneamente, e o manipulador padrão simplesmente não tem tempo de executar . Mas há um jeito! Use `register_shutdown_function()` — esta função é chamada de qualquer forma, mesmo em caso de erro fatal . ### Manipulador simples de erros fatais ```php getMessage()." | ".$e->getFile().":".$e->getLine()." | $url\n"; file_put_contents($logFile, $msg, FILE_APPEND); }); // Manipulador para erros fatais register_shutdown_function(function() use ($logFile) { $error = error_get_last(); if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) { $url = ($_SERVER['HTTP_HOST'] ?? 'CLI') . ($_SERVER['REQUEST_URI'] ?? ''); $msg = "[".date('Y-m-d H:i:s')."] [FATAL] ".$error['message']." | ".$error['file'].":".$error['line']." | $url\n"; file_put_contents($logFile, $msg, FILE_APPEND); } }); ``` Você pode inserir este código no início do seu arquivo principal (por exemplo, `index.php` ou `header.php`), e ele capturará absolutamente tudo . ## Passo 7: Logs em frameworks populares Se você usa um framework moderno, o log já está configurado, mas os caminhos dos logs são diferentes. ### Laravel Os logs são armazenados em `storage/logs/laravel.log`. Por padrão, usa Monolog; o formato pode ser texto ou JSON. Para ver erros: ```bash tail -f storage/logs/laravel.log ``` ### Symfony Logs padrão: `var/log/dev.log` e `var/log/prod.log`. Também usa Monolog, altamente configurável. ### WordPress Por padrão, o WordPress não escreve logs, mas você pode ativá-los adicionando isto ao `wp-config.php`: ```php define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); ``` Os logs estarão em `/wp-content/debug.log`. ## Passo 8: Problemas comuns e suas soluções ### Problema: Os logs não estão sendo escritos O que verificar: 1. `log_errors = On` está definitivamente configurado? 2. Há permissões de escrita para o arquivo e seu diretório? 3. Você editou o php.ini correto (verifique com `phpinfo()`)? 4. Você reiniciou o servidor web após as alterações? ### Problema: Erros fatais não estão sendo capturados Mesmo com o log ativado, às vezes os erros fatais não são escritos se ocorrerem muito cedo (por exemplo, um erro de parse no próprio arquivo onde você está ativando o log). A única solução é o posicionamento correto — no início, antes de qualquer outra coisa . ### Problema: Logs demais Se `E_ALL` estiver ativado em produção, os logs crescerão rapidamente. Configure `error_reporting` de forma sensata : ```ini error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE ``` ### Problema: Logs enchendo o disco Configure a rotação de logs com `logrotate`. Uma configuração para logs PHP: ``` /var/log/php_errors.log { daily rotate 30 compress delaycompress missingok notifempty create 644 www-data www-data } ``` ## Passo 9: Exemplo prático: Investigando uma página em branco Imagine uma situação: você abre um site e está em branco. O que fazer passo a passo? 1. **Verifique os logs do servidor web** (Apache/Nginx) — frequentemente contêm uma pista 2. **Verifique os logs PHP** — procure por entradas dos últimos minutos ```bash tail -n 50 /var/log/php_errors.log | grep -A5 -B5 "$(date +%Y-%m-%d)" ``` 3. **Encontre o erro** : ``` [2026-03-04 15:30:22] PHP Fatal error: Uncaught Error: Class 'DB' not found in /var/www/site/index.php on line 12 ``` 4. **Abra o arquivo**, verifique a linha 12 — efetivamente, você esqueceu de incluir a classe. 5. **Corrija**, teste — o site funciona! Magia! ## Referência rápida: Cola | Ação | Comando / Código | |------|------------------| | Ativar log no php.ini | `log_errors = On` + `error_log = /caminho/para/arquivo` | | Ativar no código | `ini_set('log_errors', 'On');` | | Ver últimas linhas | `tail -f /var/log/php_errors.log` | | Procurar erros fatais | `grep "Fatal error" /var/log/php_errors.log` | | Capturar erros fatais | `register_shutdown_function()` + `error_get_last()` | | Onde estão os logs do Laravel? | `storage/logs/laravel.log` | | Onde estão os logs do Symfony? | `var/log/dev.log` e `var/log/prod.log` | ## Em vez de uma conclusão O PHP não é tão assustador quanto costumam pintá-lo. Sim, a tela branca da morte é aterrorizante, mas por trás dela há sempre um erro específico que simplesmente não quer falar. Aprenda a ativar os logs, e o PHP começará a falar. As regras principais: - Em produção, **sempre** ative `log_errors` e desative `display_errors` - Escreva os logs em um arquivo dedicado, não no syslog — é mais fácil pesquisar - Use `register_shutdown_function` para capturar erros fatais - Verifique seus logs regularmente — pelo menos uma vez por dia E lembre-se: código perfeito não escreve erros. Mas se um erro ocorrer, que ele pelo menos deixe um recado. ?>