Dominando Headers HTTP em PHP: Redirecionamentos e Respostas em Projetos Reais Já leu

Headers HTTP em PHP: Redirecionamentos e Respostas O Que São Headers HTTP e Por Que Importam Headers HTTP são informações enviadas entre cliente e servidor antes do corpo da resposta. Eles controlam cache, autenticação, tipo de conteúdo e comportamento do navegador. Em PHP, manipular headers corretamente é essencial para redirecionar usuários, definir cookies, controlar acesso e estruturar respostas adequadas. A função é a ferramenta principal, mas exige cuidado: deve ser chamada antes de qualquer saída (echo, espaço em branco ou HTML). Erros ao trabalhar com headers causam "Headers already sent" — um dos problemas mais comuns em PHP. Entender o ciclo de vida da resposta HTTP evita frustrações e bugs difíceis de rastrear. Este artigo cobre desde o básico até padrões profissionais. Redirecionamentos HTTP com Redirecionamento Simples (Status 302) O redirecionamento 302 (Found) é temporário. Use quando o destino pode mudar: Sempre chame após para evitar que código abaixo execute. O navegador segue automaticamente a URL. Redirecionamento Permanente (Status 301)

Headers HTTP em PHP: Redirecionamentos e Respostas

O Que São Headers HTTP e Por Que Importam

Headers HTTP são informações enviadas entre cliente e servidor antes do corpo da resposta. Eles controlam cache, autenticação, tipo de conteúdo e comportamento do navegador. Em PHP, manipular headers corretamente é essencial para redirecionar usuários, definir cookies, controlar acesso e estruturar respostas adequadas. A função header() é a ferramenta principal, mas exige cuidado: deve ser chamada antes de qualquer saída (echo, espaço em branco ou HTML).

Erros ao trabalhar com headers causam "Headers already sent" — um dos problemas mais comuns em PHP. Entender o ciclo de vida da resposta HTTP evita frustrações e bugs difíceis de rastrear. Este artigo cobre desde o básico até padrões profissionais.

Redirecionamentos HTTP com header()

Redirecionamento Simples (Status 302)

O redirecionamento 302 (Found) é temporário. Use quando o destino pode mudar:

<?php
// Redireciona para outra página
header("Location: https://exemplo.com/nova-pagina");
exit; // Importante: encerra o script
?>

Sempre chame exit() após header("Location:") para evitar que código abaixo execute. O navegador segue automaticamente a URL.

Redirecionamento Permanente (Status 301)

Use 301 (Moved Permanently) quando uma página foi movida definitivamente:

<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: https://exemplo.com/pagina-antiga-agora-aqui");
exit;
?>

Navegadores e motores de busca armazenam 301 em cache. Use com moderação em URLs antigas para não quebrar SEO.

Redirecionamento com Validação

Padrão profissional: validar antes de redirecionar:

<?php
session_start();

// Verifica autenticação
if (!isset($_SESSION['usuario_id'])) {
    header("Location: /login.php");
    exit;
}

// Processamento normal
echo "Bem-vindo, " . htmlspecialchars($_SESSION['usuario_id']);
?>

Controle de Respostas e Headers Personalizados

Definindo Tipo de Conteúdo

O header Content-Type informa ao navegador como interpretar a resposta:

<?php
// Retornando JSON
header("Content-Type: application/json; charset=utf-8");
$dados = ['status' => 'sucesso', 'mensagem' => 'Operação concluída'];
echo json_encode($dados);
exit;
?>
<?php
// Forçando download de arquivo
header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename='documento.pdf'");
readfile('/caminho/local/documento.pdf');
exit;
?>

Cache e Headers de Controle

Controle como navegadores e proxies armazenam sua resposta:

<?php
// Desabilitar cache completamente
header("Cache-Control: no-cache, no-store, must-revalidate");
header("Pragma: no-cache");
header("Expires: 0");

// Para conteúdo estático (imagens, CSS)
header("Cache-Control: public, max-age=86400"); // 1 dia
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 86400) . " GMT");
?>

Headers de Segurança

Implemente proteções essenciais:

<?php
// Previne clickjacking
header("X-Frame-Options: SAMEORIGIN");

// Previne MIME sniffing
header("X-Content-Type-Options: nosniff");

// Ativa proteção XSS no navegador
header("X-XSS-Protection: 1; mode=block");

// CORS - controla requisições cross-origin
header("Access-Control-Allow-Origin: https://dominio-confiavel.com");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
?>

Códigos de Status HTTP

Respostas de Sucesso (2xx)

<?php
// 200 OK - resposta bem-sucedida padrão (implícito)
header("HTTP/1.1 200 OK");
echo "Operação realizada com sucesso";

// 201 Created - recurso criado
header("HTTP/1.1 201 Created");
header("Location: /recurso/123");
echo json_encode(['id' => 123]);
?>

Erros do Cliente (4xx)

<?php
// 400 Bad Request
header("HTTP/1.1 400 Bad Request");
http_response_code(400);
echo json_encode(['erro' => 'Dados inválidos']);
exit;

// 403 Forbidden
if (!$usuario_autorizado) {
    header("HTTP/1.1 403 Forbidden");
    http_response_code(403);
    echo "Acesso negado";
    exit;
}

// 404 Not Found
header("HTTP/1.1 404 Not Found");
http_response_code(404);
echo "Página não encontrada";
exit;
?>

Erros do Servidor (5xx)

<?php
// 500 Internal Server Error
try {
    // Processamento perigoso
    $resultado = operacao_critica();
} catch (Exception $e) {
    header("HTTP/1.1 500 Internal Server Error");
    http_response_code(500);
    echo json_encode(['erro' => 'Erro interno do servidor']);
    error_log($e->getMessage());
    exit;
}
?>

Boas Práticas e Armadilhas

Evite espaços em branco antes de <?php:

<?php // Correto - sem espaço antes da tag
header("Location: /home");
exit;
?>
<?php
// Errado - espaço/quebra de linha depois de ?>
?>

header("Location: /home");

Use http_response_code() para compatibilidade moderna:

<?php
http_response_code(301);
header("Location: /nova-url");
exit;

// Ou verifique headers já enviados
if (!headers_sent()) {
    header("Content-Type: application/json");
} else {
    // Fallback com JavaScript
    echo "<script>window.location='/nova-url';</script>";
}
?>

Conclusão

Dominar headers HTTP em PHP é fundamental para criar aplicações robustas e seguras. Os três pontos principais aprendidos são: (1) Headers devem ser enviados antes de qualquer saída, usando header() corretamente e sempre chamando exit() após redirecionamentos; (2) Escolher o código de status apropriado (301 vs 302, 200 vs 201, 4xx vs 5xx) comunica intenção clara ao cliente e aos motores de busca; (3) Implementar headers de segurança (X-Frame-Options, CORS, Cache-Control) é obrigação, não opcional, para proteger usuários e dados.

Pratique criando um sistema simples de autenticação com redirecionamentos condicionais e respostas JSON. O aprendizado consolidado só vem com experiência prática.

Referências


Artigos relacionados