Função PHP headers_sent(): Tudo o Que Você Precisa Saber
Como desenvolvedor PHP, você pode precisar verificar se os cabeçalhos HTTP já foram enviados ao cliente. A função headers_sent() é uma função nativa do PHP
Toda resposta HTTP é dividida em duas partes: um bloco de cabeçalhos (código de status, Content-Type, cookies, redirecionamentos) seguido pelo corpo da resposta. O detalhe é que os cabeçalhos devem ser enviados antes de qualquer saída do corpo. No momento em que o PHP envia um único byte do corpo, ele libera os cabeçalhos e os bloqueia — qualquer chamada posterior a header(), setcookie() ou session_start() dispara o famoso aviso Cannot modify header information - headers already sent.
headers_sent() é a função nativa que permite perguntar, antes de tentar enviar um cabeçalho, se já é tarde demais. Este guia aborda sua sintaxe, seus parâmetros por referência, o que causa saída prematura e como corrigi-la.
O Que headers_sent() Faz
headers_sent() retorna um boolean:
true— os cabeçalhos já foram enviados (a saída começou). Qualquer chamada posterior aheader()/setcookie()falhará.false— nenhuma saída foi iniciada ainda, portanto ainda é seguro definir cabeçalhos.
Proteger a lógica de cabeçalhos com headers_sent() permite evitar o aviso e degradar graciosamente (por exemplo, registrar o problema ou recorrer a um redirecionamento JavaScript) em vez de travar a página.
Sintaxe
headers_sent(string &$filename = null, int &$line = null): boolAmbos os parâmetros são opcionais e passados por referência. Quando os cabeçalhos já foram enviados, o PHP os preenche com a localização da saída que os iniciou:
$filename— o nome do arquivo fonte onde a saída começou pela primeira vez.$line— o número da linha dentro desse arquivo.
É isso que torna headers_sent() tão útil para depuração: ela aponta diretamente para o culpado.
Uso Básico
Verifique o valor de retorno antes de enviar um cabeçalho:
<?php
if (!headers_sent()) {
header('Location: /dashboard');
exit;
}
echo 'Headers were already sent, cannot redirect via HTTP.';Se a saída não foi iniciada, o cabeçalho de redirecionamento é enviado. Caso contrário, o script evita o aviso fatal e exibe uma mensagem alternativa.
Encontrando Onde a Saída Começou
Passe as duas variáveis de referência para descobrir exatamente o que enviou os cabeçalhos — inestimável quando um espaço perdido ou echo está enterrado em um arquivo incluído:
<?php
if (headers_sent($file, $line)) {
echo "Headers already sent in $file on line $line";
} else {
setcookie('theme', 'dark');
echo 'Cookie set successfully.';
}Se a condição for verdadeira, você recebe uma mensagem como Headers already sent in /var/www/header.php on line 12, indicando precisamente onde procurar.
O Que Dispara "Headers Already Sent"
Qualquer coisa que produza saída no corpo antes da chamada ao cabeçalho libera os cabeçalhos. Causas comuns:
- Espaço em branco ou uma linha em branco antes de
<?php— mesmo um espaço ou quebra de linha conta como saída. - Uma quebra de linha após o
?>de fechamento de um arquivo incluído. (Melhor prática: omitir o?>de fechamento em arquivos puramente PHP.) echo,print,printfouvar_dumpexecutados antes do cabeçalho.- Um arquivo UTF-8 salvo com BOM (marca de ordem de byte) — esses bytes iniciais invisíveis são saída.
- Avisos/notificações do PHP exibidos na página (quando
display_errorsestá ativo) antes dos cabeçalhos.
Corrigindo com Buffer de Saída
Se não for possível reordenar o código para que todos os cabeçalhos venham primeiro, envolva o script em um buffer de saída. ob_start() mantém o corpo em memória em vez de enviá-lo imediatamente, para que os cabeçalhos permaneçam modificáveis até que o buffer seja liberado:
<?php
ob_start(); // start buffering — nothing is sent yet
echo 'Some early output';
// Still safe: the echo above is held in the buffer, headers are not sent
setcookie('user', 'jane');
header('X-App-Version: 2.0');
ob_end_flush(); // now send headers, then the buffered bodyComo a saída está em buffer, headers_sent() ainda retornaria false após o echo, e as chamadas posteriores a setcookie() e header() teriam sucesso.
Funções Relacionadas
header()— envia um cabeçalho HTTP bruto.headers_list()— lista os cabeçalhos na fila ou já enviados.setcookie()— define um cookie (envia um cabeçalhoSet-Cookie).ob_start()— inicia o buffer de saída para atrasar o envio dos cabeçalhos.- PHP Sessions —
session_start()também envia cabeçalhos e é um gatilho frequente.
Conclusão
headers_sent() é uma guarda pequena, mas essencial: chame-a antes de qualquer header(), setcookie() ou session_start() para verificar se a saída já começou. Quando retorna true, os argumentos por referência $filename e $line identificam com precisão a saída problemática para que você possa corrigi-la — ou envolva seu script em ob_start() para manter os cabeçalhos modificáveis até que você esteja pronto para liberar.