Función header() de PHP: Todo lo que necesitas saber
Como desarrollador PHP, puedes necesitar manipular cabeceras HTTP en tu aplicación web. La función header() es una herramienta potente para establecer HTTP
Cada respuesta HTTP que envía un servidor web tiene dos partes: un conjunto de cabeceras (metadatos como el tipo de contenido, las reglas de caché y el código de estado) seguidas del cuerpo de la respuesta (el HTML, JSON, imagen o archivo que recibe el navegador). La función header() de PHP te permite escribir esas cabeceras desde tu script, para poder redirigir usuarios, servir descargas, establecer el tipo de contenido, controlar el caché y enviar códigos de estado personalizados.
Esta guía cubre la sintaxis y los parámetros de header(), la regla que casi todo el mundo pasa por alto (el error "headers already sent") y las recetas más comunes del mundo real.
¿Qué es la función header()?
header() es una función integrada de PHP que envía una cabecera HTTP sin procesar al cliente. Una cabecera es una sola línea como Content-Type: text/html o Location: /login que el navegador lee antes del cuerpo de la página. Debido a que las cabeceras van primero en la respuesta, header() solo funciona mientras PHP todavía está construyendo esa sección de cabeceras — consulta la regla "headers already sent" más abajo.
Sintaxis y parámetros
header(string $header, bool $replace = true, int $response_code = 0): void| Parámetro | Tipo | Descripción |
|---|---|---|
$header | string | La línea de cabecera a enviar, p. ej. "Content-Type: application/json". |
$replace | bool | Si esta llamada reemplaza una cabecera previa del mismo nombre. Cuando es false, se envían varias cabeceras con el mismo nombre. Por defecto es true. |
$response_code | int | Fuerza el código de estado HTTP de la respuesta. 0 (el valor predeterminado) significa "dejar el estado sin cambios". |
La función no devuelve nada (void). No indica si la cabecera fue aceptada — si ya se envió alguna salida, emite una advertencia.
Establecer una cabecera
El uso más sencillo es declarar qué tipo de contenido contiene la respuesta. Esto es esencial cuando tu script devuelve JSON, XML, texto plano o un archivo en lugar de HTML:
<?php
header("Content-Type: application/json");
echo json_encode(["status" => "ok", "id" => 42]);La cabecera Content-Type le indica al navegador que trate el cuerpo como JSON, por lo que analiza {"status":"ok","id":42} como datos en lugar de renderizarlo como una página web.
La regla "headers already sent"
Esta es la cosa más importante que debes saber sobre header(): debe llamarse antes de que cualquier salida salga de tu script. La salida incluye HTML, echo/print, var_dump() e incluso un espacio o línea en blanco antes de la etiqueta de apertura <?php. Una vez que se ha enviado un byte del cuerpo, la sección de cabeceras se cierra y PHP lanza:
Warning: Cannot modify header information - headers already sentTienes dos formas de evitarlo:
<?php
// 1. Check first — useful when a header is optional
if (!headers_sent()) {
header("X-Powered-By: MyApp");
}
// 2. Buffer output so nothing is flushed until you choose to
ob_start(); // capture everything that gets echoed
echo "page content...";
header("X-Cache: MISS"); // still works — body is held in the buffer
ob_end_flush(); // now send headers + buffered body togetherUna causa común es que un editor guarde el archivo con un BOM UTF-8 o una nueva línea después de ?>. Omitir completamente la etiqueta de cierre ?> en archivos PHP puros es la forma recomendada de evitarlo.
Casos de uso comunes
Redirigir a otra URL
Envía una cabecera Location y luego detén el script para que no se ejecute más código:
<?php
header("Location: https://example.com/login");
exit; // always exit after a redirectPor defecto, esto es una redirección 302 Found (temporal). Para un traslado permanente, pasa 301 como código de estado para que los motores de búsqueda actualicen su índice:
<?php
// 301 Moved Permanently
header("Location: https://example.com/new-page", true, 301);
exit;Enviar un código de estado personalizado
Puedes establecer un estado sin redirigir — por ejemplo, para una API que devuelve "no encontrado":
<?php
header("HTTP/1.1 404 Not Found");
// or, more portably:
header("Status: 404 Not Found", true, 404);
echo "Resource not found";Para códigos de estado en concreto, la función dedicada http_response_code() es más clara y fácil de leer.
Forzar la descarga de un archivo
Combina Content-Type con Content-Disposition: attachment para que el navegador guarde el archivo en lugar de mostrarlo:
<?php
$file = "report.pdf";
header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-Length: " . filesize($file));
readfile($file); // stream the file to the client
exit;Consulta readfile() para transmitir el contenido del archivo a la salida.
Controlar el caché del navegador
Las cabeceras te permiten indicarle al navegador si puede (y por cuánto tiempo) reutilizar una respuesta:
<?php
// Tell the browser never to cache this response
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Expires: 0");Enviar varias cabeceras con el mismo nombre
La mayoría de las cabeceras reemplazan cualquier cabecera anterior con el mismo nombre. Establece el segundo argumento en false cuando genuinamente necesitas más de una (raro, pero válido para algunas cabeceras):
<?php
header("X-Sample: first");
header("X-Sample: second", false); // both X-Sample headers are sentFunciones relacionadas
header() escribe una cabecera a la vez, pero PHP tiene ayudantes de nivel superior para los casos más comunes:
setcookie()ysetrawcookie()— establecen una cabeceraSet-Cookiesin tener que formatearla a mano. Consulta PHP Cookies.http_response_code()— lee o establece el código de estado.- PHP Sessions —
session_start()en sí misma envía cabeceras de cookies, por lo que tiene el mismo requisito de "antes de la salida".
Para profundizar en la definición y llamada de tus propias funciones, consulta PHP Functions.
Conclusión
La función header() es tu línea directa a las cabeceras de respuesta HTTP en PHP. Las reglas son simples: construye la cadena de cabecera, llama a header() antes de cualquier salida y usa exit después de una redirección. Con ella puedes redirigir usuarios, establecer tipos de contenido, servir descargas, enviar códigos de estado y controlar el caché — los bloques de construcción de casi cualquier respuesta PHP dinámica.