La función header() en PHP envía cabeceras HTTP al navegador antes de que se envíe cualquier contenido. Sirve para redirigir al usuario, indicar el tipo de respuesta, forzar descargas o establecer códigos de estado. Entender cómo y cuándo usarla, junto con el output buffering, es esencial para controlar la comunicación entre el servidor y el cliente.
Redirecciones con header() y exit
La redirección más habitual consiste en enviar la cabecera Location. Es imprescindible llamar a exit o die justo después para que PHP no siga ejecutando código tras la redirección.
<?php
// Redirección permanente (301): la URL ha cambiado definitivamente
http_response_code(301);
header('Location: https://programacion.net/nueva-url');
exit;
// Redirección temporal (302): la URL puede cambiar en el futuro
header('Location: /login', true, 302);
exit;
// Post/Redirect/Get: tras procesar un formulario, redirigir para evitar reenvío
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// ... procesar formulario ...
header('Location: /gracias?ok=1');
exit; // sin exit, el código posterior se ejecuta igualmente
}
?>
Content-Type para APIs JSON y descargas
La cabecera Content-Type indica al cliente el formato de la respuesta. Para APIs JSON es application/json; para forzar una descarga se usa Content-Disposition junto con el tipo de contenido del fichero.
<?php
// Respuesta JSON para una API REST
header('Content-Type: application/json; charset=utf-8');
http_response_code(200);
echo json_encode(['estado' => 'ok', 'datos' => $resultado]);
exit;
// Forzar descarga de un fichero PDF
$ruta = '/var/datos/informe.pdf';
if (!file_exists($ruta)) {
http_response_code(404);
exit;
}
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="informe-2024.pdf"');
header('Content-Length: ' . filesize($ruta));
header('Cache-Control: no-store');
readfile($ruta);
exit;
?>
http_response_code(): códigos de estado HTTP
http_response_code() establece el código de estado de la respuesta. Llamarlo sin argumentos devuelve el código actual. Es más legible que pasar el código como tercer argumento de header().
<?php
// Respuesta 201 Created para una API que crea un recurso
http_response_code(201);
header('Content-Type: application/json; charset=utf-8');
header('Location: /api/usuarios/42');
echo json_encode(['id' => 42, 'nombre' => 'Ana']);
exit;
// 404 con página personalizada
http_response_code(404);
header('Content-Type: text/html; charset=utf-8');
include __DIR__ . '/plantillas/404.php';
exit;
// 422 Unprocessable Entity cuando la validación falla
http_response_code(422);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['errores' => ['El email ya está en uso.']]);
exit;
?>
Output buffering con ob_start()
Por defecto, PHP envía las cabeceras en cuanto aparece la primera salida. El output buffering retiene esa salida en memoria, lo que permite llamar a header() aunque ya haya HTML generado.
<?php
ob_start(); // iniciar buffer
echo '<!-- este HTML queda en el buffer -->';
echo '<p>Contenido generado antes de saber si redirigir.</p>';
$necesitaRedireccion = verificarCondicion();
if ($necesitaRedireccion) {
ob_end_clean(); // descartar el buffer y las cabeceras no enviadas
header('Location: /otra-pagina');
exit;
}
// Modificar el buffer antes de enviarlo
$contenido = ob_get_contents();
ob_end_clean();
$contenidoMinificado = str_replace(' ', ' ', $contenido);
echo $contenidoMinificado;
// ob_start con función de transformación
ob_start('mb_strtolower'); // transforma toda la salida a minúsculas al enviar
echo 'ESTE TEXTO SALDRÁ EN MINÚSCULAS';
ob_end_flush();
?>
headers_sent() para depurar
headers_sent() devuelve true si ya se han enviado cabeceras y por lo tanto ya no es posible modificarlas. Aceptar un segundo y tercer parámetro por referencia permite obtener el fichero y la línea donde ocurrió el primer envío de salida.
<?php
if (headers_sent($fichero, $linea)) {
echo "No se pueden enviar más cabeceras. ";
echo "La primera salida fue en $fichero en la línea $linea.";
} else {
header('X-Mi-Cabecera: valor');
}
?>
La documentación oficial de header() y la de control de salida (output buffering) detallan todas las cabeceras reconocidas por PHP, el manejo de niveles anidados de buffer y las funciones disponibles para manipular el contenido antes de enviarlo al cliente.
