Funciones de Control de Salida en PHP: Todo lo que Necesitas Saber
Aprende el buffer de salida en PHP y las funciones ob_*: ob_start, ob_get_clean, ob_end_flush, callbacks y errores comunes, con ejemplos.
Normalmente, cada echo, print o fragmento de HTML en un script PHP se envía al navegador en el momento en que se ejecuta. El buffer de salida te permite interceptar esa salida y retenerla en memoria (un buffer) en lugar de enviarla, para que puedas inspeccionarla, editarla, descartarla o enviarla más tarde. Las funciones de control de salida de PHP son las herramientas integradas que gestionan este buffer.
Este capítulo explica qué es el buffer de salida, por qué resuelve problemas reales y cómo funciona cada función ob_* — con ejemplos ejecutables.
Por qué importa el buffer de salida
El buffer de salida es más que una curiosidad. Resuelve varios problemas cotidianos de PHP:
- Evitar errores de "headers already sent". En PHP debes llamar a
header()ysetcookie()antes de que cualquier salida llegue al navegador. Al almacenar la salida en buffer, puedes seguir enviando cabeceras después de que tus plantillas se hayan ejecutado, porque nada se ha enviado aún. Consulta headers_sent(). - Capturar la salida como string. Renderiza una plantilla o incluye un archivo y obtén su resultado como variable en lugar de imprimirlo — la base de la mayoría de los motores de plantillas simples.
- Post-procesar toda la página. Minifica HTML, reemplaza marcadores de posición o comprime la salida (gzip) en un solo lugar antes de enviarla.
- Descartar salida no deseada. Elimina el ruido de una biblioteca de terceros o una sentencia de depuración que no quieres que el usuario vea.
Las funciones de control de salida
Estas son las funciones que más usarás. Todas operan sobre el buffer iniciado por ob_start().
| Función | Qué hace |
|---|---|
ob_start() | Inicia un nuevo buffer de salida. La captura comienza desde este punto. |
ob_get_contents() | Devuelve el contenido actual del buffer sin detener el buffer. |
ob_get_length() | Devuelve el número de bytes actualmente en el buffer. |
ob_get_level() | Devuelve el nivel de anidamiento (cuántos buffers están apilados). |
ob_clean() | Vacía el buffer pero mantiene el buffering activo. |
ob_get_clean() | Devuelve el contenido y desactiva el buffer — una combinación habitual. |
ob_end_clean() | Descarta el buffer y desactiva el buffering (no devuelve nada). |
ob_flush() / ob_end_flush() | Envía el buffer al navegador; ob_end_flush() también detiene el buffering. |
Capturar la salida como string
El uso más común del buffering es tomar lo que imprime un bloque de código y almacenarlo en una variable. ob_get_clean() devuelve el buffer y detiene el buffering en una sola llamada:
Nada llega al navegador hasta el echo final, que imprime HELLO, WORLD!. Capturamos el texto, lo transformamos y solo entonces lo enviamos. Así es exactamente como funciona una pequeña función de plantilla:
<?php
function renderTemplate(string $name): string {
ob_start();
echo "Hello, $name!";
return ob_get_clean(); // contents + stop buffering
}
echo renderTemplate("Ada");Esto imprime Hello, Ada!. En un proyecto real, el bloque en buffer sería una plantilla HTML completa con etiquetas <?= $name ?> incrustadas.
Enviar el buffer al navegador
Cuando solo quieres retrasar la salida (no capturarla), usa ob_end_flush() para enviar todo de una vez:
Mientras el buffer está abierto también puedes inspeccionarlo con ob_get_length() y ob_get_level():
<?php
ob_start();
echo "buffered text";
echo "\nLevel: " . ob_get_level(); // 1 — one buffer is active
echo "\nLength: " . ob_get_length(); // bytes captured so far
ob_end_flush();ob_get_level() devuelve 1 porque hay un solo buffer activo; si llamas a ob_start() de nuevo dentro de él, el nivel pasa a ser 2 (los buffers se apilan como una pila).
Transformar la salida con un callback
ob_start() acepta un callback que recibe el buffer completo y devuelve la versión modificada. Así es como funcionan los minificadores de salida y los filtros de búsqueda y reemplazo:
<?php
ob_start(function (string $buffer): string {
return str_replace("cat", "dog", $buffer);
});
echo "I have a cat.";
ob_end_flush();El callback se ejecuta cuando el buffer se vacía, por lo que la página imprime I have a dog.. El mismo patrón es el que usa ob_gzhandler, el callback integrado de PHP para comprimir la salida con gzip.
Errores comunes
- Cierra siempre lo que abres. Cada
ob_start()debe tener su correspondiente llamada a flush o clean. Un buffer sin cerrar deja la salida atrapada en memoria y nunca llega al usuario. - Los buffers se anidan. Cada
ob_start()añade un nivel.ob_get_clean()solo cierra el más interno; usaob_get_level()en un bucle si necesitas cerrar varios. ob_get_contents()no detiene el buffering — solo lo hacen las funciones*_cleany*_end_*. Confundirlas es una fuente frecuente de salida duplicada.- Un buffer tiene un tamaño finito. Por defecto PHP vacía automáticamente el buffer cuando alcanza los bytes de
output_buffering(php.ini), así que no confíes en que puede retener una cantidad ilimitada de datos.
Conclusión
El buffer de salida te da control sobre cuándo y cómo se envía la salida de tu script. Úsalo para capturar contenido renderizado como string, para enviar cabeceras después de generar una página, para descartar salida no deseada o para post-procesar toda la respuesta en un solo lugar. Una vez que comprendes el ciclo start/get/clean/flush, la familia ob_* es pequeña y predecible.
Lectura relacionada: echo y print, PHP header(), Sesiones PHP y Cookies PHP.