Headers e redirecionamentos
Esta aula aborda o uso da função header() em PHP para enviar cabeçalhos HTTP, com foco em redirecionamentos via Location, códigos de status e cuidados com output buffering. O aluno aprenderá a manipular headers de forma segura e eficiente.
Headers HTTP são metadados enviados entre o servidor e o cliente, essenciais para controlar comportamento de cache, redirecionamentos, tipo de conteúdo e muito mais. Em PHP, a função header() é a principal ferramenta para manipular esses cabeçalhos diretamente no script.
Nesta aula, vamos explorar como usar header() para redirecionar o navegador, definir códigos de status HTTP e evitar erros comuns relacionados ao envio prematuro de saída. Compreender esses conceitos é fundamental para construir aplicações web robustas e seguras.
header()
A função header() envia um cabeçalho HTTP bruto ao cliente. Ela deve ser chamada antes de qualquer saída (echo, HTML, espaços em branco) para funcionar corretamente. Sua sintaxe básica é:
header(string $header, bool $replace = true, int $response_code = 0): voidO primeiro parâmetro é a string do cabeçalho, como "Content-Type: text/html". O segundo parâmetro ($replace) indica se o cabeçalho deve substituir um anterior do mesmo tipo (padrão true) ou adicionar outro (false). O terceiro permite forçar um código de resposta HTTP.
Exemplo de definição de tipo de conteúdo:
header('Content-Type: application/json');
echo json_encode(['status' => 'ok']);Este cabeçalho informa ao cliente que a resposta é JSON, permitindo que o navegador ou API processe corretamente.
Redirecionamento (Location)
O redirecionamento é feito com o cabeçalho Location, que instrui o navegador a ir para outra URL. Deve ser acompanhado de um código de status 3xx (geralmente 302 para redirecionamento temporário ou 301 para permanente). Exemplo:
header('Location: https://example.com/novo-caminho');
exit;É importante chamar exit (ou die) após o redirecionamento para garantir que o script pare de executar, evitando que código adicional seja enviado ao cliente. Caso contrário, o navegador pode ignorar o redirecionamento se houver saída posterior.
Para redirecionamentos permanentes, use o código 301:
header('Location: https://example.com/nova-pagina', true, 301);
exit;O segundo parâmetro true (padrão) garante que qualquer cabeçalho Location anterior seja substituído.
Códigos HTTP
Códigos de status HTTP indicam o resultado de uma requisição. Os mais comuns em redirecionamentos são:
- 301 Moved Permanently: recurso movido permanentemente; navegadores e mecanismos de busca atualizam o link.
- 302 Found: redirecionamento temporário; o recurso original ainda é válido.
- 303 See Other: usado após POST para redirecionar para uma página GET (evita reenvio de formulário).
- 307 Temporary Redirect: similar ao 302, mas garante que o método HTTP não seja alterado.
- 308 Permanent Redirect: similar ao 301, mas mantém o método HTTP.
Para definir o código de resposta, use http_response_code() ou o terceiro parâmetro de header(). Exemplo:
http_response_code(404);
echo 'Página não encontrada';É boa prática usar códigos apropriados para cada situação, melhorando a semântica e o SEO.
Cuidados (output buffering)
Um erro comum é tentar enviar headers após já ter enviado saída (HTML, espaços, etc.). Isso gera o aviso "Cannot modify header information - headers already sent". Para evitar, use output buffering, que armazena a saída em buffer até que seja liberada.
Ative o buffer com ob_start() no início do script. Assim, mesmo que haja saída antes de header(), o PHP não envia nada imediatamente. Exemplo:
ob_start();
echo 'Algum texto'; // não é enviado ainda
header('Location: https://example.com');
ob_end_flush(); // envia tudo e libera o buffer
exit;Funções úteis:
ob_start(): inicia o buffer de saída.ob_end_flush(): envia o buffer e desliga o buffer.ob_end_clean(): descarta o buffer sem enviar.ob_get_contents(): obtém o conteúdo atual do buffer sem enviar.
Outra prática é verificar se headers já foram enviados com headers_sent():
if (!headers_sent()) {
header('Location: https://example.com');
exit;
} else {
echo 'Não foi possível redirecionar';
}Isso permite tomar ações alternativas em vez de gerar erro.
Boas práticas e observações finais
- Sempre use
exitapós redirecionamentos para evitar execução desnecessária. - Prefira códigos HTTP semânticos (301 para permanente, 302 para temporário).
- Evite enviar saída antes de headers; use output buffering se necessário.
- Teste os cabeçalhos com ferramentas como o console do navegador (Network tab) ou
curl -I. - Para redirecionamentos internos, use URLs relativas ou absolutas completas.
Referências
- PHP Manual: header()
- PHP Manual: http_response_code()
- MDN: Códigos de status HTTP
- PHP Manual: ob_start()
- PHP Manual: headers_sent()
- MDN: Location header
Exercícios
Crie um script PHP que redirecione permanentemente (301) o usuário para
https://www.example.com.✓ Resposta:header('Location: https://www.example.com', true, 301); exit;Escreva um código que defina o cabeçalho
Content-Typecomotext/plaine exiba a mensagem "Olá, mundo!" sem usar output buffering.✓ Resposta:header('Content-Type: text/plain'); echo 'Olá, mundo!';Implemente um script que verifique se o cabeçalho já foi enviado. Se não, redirecione para
/login; caso contrário, exiba "Redirecionamento não possível".✓ Resposta:if (!headers_sent()) { header('Location: /login'); exit; } else { echo 'Redirecionamento não possível'; }Corrija o código abaixo que gera erro "headers already sent":
echo 'Antes'; header('Location: /destino'); exit;✓ Resposta:Use output buffering:ob_start(); echo 'Antes'; header('Location: /destino'); ob_end_flush(); exit;Crie um script que redirecione para
/sucessocom código 303 após um POST (simule usando$_SERVER['REQUEST_METHOD']).✓ Resposta:if ($_SERVER['REQUEST_METHOD'] === 'POST') { header('Location: /sucesso', true, 303); exit; }