Conheça o "Headers already sent" — seu novo inimigo (e amigo)
\n\nSe você já escreveu em PHP, com certeza já se deparou com esse erro. Ele aparece do nada, geralmente no pior momento — quando você quase terminou o script. A mensagem é assustadora, vermelha, e parece que todo o código quebrou. Mas, na verdade, este é um dos erros mais úteis do PHP. Ele te ensina a trabalhar corretamente com o protocolo HTTP.
\n\nNeste tutorial, vamos entender por que o erro Headers already sent acontece, como diagnosticá-lo e, principalmente, como corrigi-lo de uma vez por todas. Não vamos apenas copiar uma resposta do Stack Overflow — vamos entender a essência. Vamos nessa!
O que são cabeçalhos HTTP e por que o PHP reclama deles?
\n\nAntes de tratar, precisamos entender a anatomia. Quando o PHP envia uma resposta para o navegador, ele faz isso em duas etapas:
\n\n- \n
- Primeiro — os cabeçalhos (headers). São informações de serviço: tipo de conteúdo (
Content-Type), codificação, cookies, status da resposta (200 OK, 404 Not Found). \n - Depois — o corpo da resposta (body). É o HTML, texto, JSON — o que o usuário vê. \n
O problema é que o PHP não pode enviar cabeçalhos depois de começar a enviar o corpo. Se você tentar chamar header() após já ter enviado qualquer caractere (até mesmo um espaço), o PHP exibirá o erro:
Warning: Cannot modify header information - headers already sent by (output started at /caminho/para/arquivo.php:12)\n\nÉ simples assim. O erro não é fatal — ele apenas avisa que seu header() não funcionou. Mas as consequências podem ser sérias: o redirecionamento não será executado, o cookie não será definido, a resposta JSON será corrompida.
Top 5 causas desse erro
\n\nVamos analisar os cenários mais comuns. Se identifica com algum?
\n\n1. Espaço ou linha em branco antes de <?php
\n\nIsso é clássico. Você abre o arquivo e, antes da tag de abertura <?php, há um espaço, uma linha em branco ou um caractere BOM (Byte Order Mark). O PHP interpreta esse caractere como parte da saída — e pronto.
// ❌ Erro: espaço antes de <?php\n <?php\nheader('Location: /nova-pagina.php');\n?>\n\n// ✅ Correto: nenhum caractere antes de <?php\n<?php\nheader('Location: /nova-pagina.php');\n?>\n\n2. Saída com echo ou print antes de header()
\n\nUm erro lógico, mas comum entre iniciantes: primeiro exibir algo e depois tentar redirecionar o usuário.
\n\n<?php\necho "Olá, mundo!";\nheader('Location: /obrigado.php'); // ❌ Erro: já houve saída\n?>\n\n3. Código HTML antes do bloco PHP
\n\nO arquivo pode ter código misturado: primeiro a marcação HTML, depois a lógica PHP com header().
<!DOCTYPE html>\n<html>\n<head>\n <title>Meu site</title>\n</head>\n<body>\n<?php\nheader('Location: /login.php'); // ❌ Erro: HTML já foi enviado\n?>\n</body>\n</html>\n\n4. Erros do PHP e funções como var_dump()
\n\nO script pode exibir avisos ou informações de depuração antes da chamada header(). Por exemplo, se você tiver display_errors ativado e o PHP exibir um warning.
<?php\nvar_dump($alguma_variavel); // Exibe dados\nheader('Content-Type: application/json'); // ❌ Erro\n?>\n\n5. Caracteres invisíveis em arquivos incluídos (include/require)
\n\nVocê inclui um arquivo com include ou require, e no final desse arquivo há uma linha em branco ou espaço extra após o fechamento ?>.
// config.php\n<?php\n$db_host = 'localhost';\n?>\n // ← Esse espaço depois de ?> estraga tudo!\n\nComo encontrar a origem do problema: diagnóstico passo a passo
\n\nO mais importante é que o erro sempre indica exatamente onde a saída começou. Leia a mensagem com atenção