Función PHP ob_flush(): Todo lo que necesitas saber
Aprende a usar ob_flush() en PHP para enviar el buffer de salida al cliente de forma inmediata sin cerrar el buffer, ideal para streaming progresivo.
Por defecto, PHP retiene la salida en un buffer y la envía al cliente de una vez. A veces querrás enviar lo que tienes hasta el momento al navegador sin cerrar el buffer — por ejemplo, para transmitir un informe largo fila por fila o mostrar el progreso durante una tarea lenta. La función ob_flush() hace exactamente eso: envía el contenido del buffer de salida activo al siguiente nivel y luego lo vacía, manteniendo el buffering activo para que puedas seguir recopilando salida. Este capítulo explica cómo encaja ob_flush() en la cadena de buffers de salida de PHP, cuándo utilizarla y los errores comunes que suelen surgir.
Qué hace ob_flush()
ob_flush() envía el contenido del buffer de salida más superior al siguiente nivel — el siguiente buffer en la pila, o la capa de escritura interna de PHP si este es el único buffer. Tras el vaciado, ese buffer queda vacío pero permanece abierto, por lo que los echos posteriores vuelven a ser capturados.
Signature: ob_flush(): void
Returns: nothing (void); emits a warning if no buffer is active
PHP: 4.0+ (return type became void in PHP 8.0)Hay dos conceptos fáciles de confundir:
ob_flush()mueve datos fuera del buffer de PHP pero no garantiza que lleguen al navegador. Puede haber otro buffer por encima, más el propio buffer de escritura de PHP y el buffer del servidor web.flush()empuja los buffers de escritura de PHP hacia el cliente. Para que los bytes lleguen realmente al cable, normalmente hay que llamar a ambos, en orden:ob_flush()y luegoflush().
Debe usarse junto con ob_start(). Llamar a ob_flush() cuando no hay ningún buffer activo genera un notice/warning y no hace nada.
Sintaxis
ob_flush();No recibe argumentos y no devuelve ningún valor.
Ejemplo básico
Habilita el buffering, escribe algo y luego vacíalo:
<?php
ob_start(); // 1. Enable output buffering
echo "This will be buffered";
ob_flush(); // 2. Flush PHP buffer to the next level
flush(); // 3. Push it toward the clientSalida:
This will be bufferedob_start() abre un buffer, el echo se captura en él, ob_flush() libera ese texto y flush() lo empuja hacia el navegador. Es importante destacar que el buffer sigue abierto después de esto — podrías hacer echo y vaciar de nuevo.
Transmitir salida de forma progresiva
El uso real más habitual de ob_flush() es enviar la salida en fragmentos para que el usuario vea los resultados a medida que se producen, en lugar de esperar a que termine todo el script:
<?php
ob_start();
for ($i = 1; $i <= 5; $i++) {
echo "Processing item $i\n";
ob_flush(); // hand this line to the next level
flush(); // and on toward the browser
// sleep(1); // (a real task would do work here)
}Salida:
Processing item 1
Processing item 2
Processing item 3
Processing item 4
Processing item 5En un servidor real con sleep(1) descomentado, cada línea aparecería con un segundo de diferencia en lugar de aparecer todas al final.
ob_flush() vs. ob_end_flush() vs. ob_get_clean()
Elegir la función de vaciado incorrecta es la fuente habitual de errores. Se diferencian en dos aspectos: si el buffer permanece abierto y adónde va el contenido.
| Función | ¿Envía el contenido? | ¿Mantiene el buffer abierto? |
|---|---|---|
ob_flush() | Sí | Sí — continúa el buffering |
ob_end_flush() | Sí | No — cierra el buffer |
ob_get_clean() | No — lo devuelve como string | No — cierra el buffer |
Usa ob_flush() cuando quieras emitir progreso pero continuar con el buffering. Usa ob_end_flush() cuando hayas terminado completamente. Usa ob_get_clean() cuando quieras capturar el buffer en una variable en lugar de enviarlo.
Errores comunes
- El buffering del servidor puede seguir reteniendo la salida. Apache, Nginx (buffering FastCGI), la compresión gzip y los proxies pueden retener los bytes vaciados hasta tener "suficiente".
ob_flush()+flush()solo controlan el lado de PHP. zlib.output_compressionrompe el streaming. Cuando la compresión gzip de salida está activada, los vaciados intermedios suelen almacenarse en buffer para la compresión, por lo que los fragmentos no llegarán de forma gradual. Desactívala para los endpoints de streaming.- Sin buffer = advertencia. Llamar a
ob_flush()sin unob_start()correspondiente genera una advertencia. Comprueba el nivel activo conob_get_level()si no estás seguro. - Vacía el buffer. Tras
ob_flush(), el buffer se limpia, por lo que no puedes leer su contenido anterior después. - Forzar el vaciado inmediato de forma global.
ob_implicit_flush(true)hace que cada sentencia de salida se vacíe automáticamente, eliminando la necesidad de llamar aob_flush()tras cadaecho.
Conclusión
ob_flush() envía el buffer de salida actual al siguiente nivel manteniendo el buffering habilitado, lo que la convierte en la herramienta adecuada para transmitir progreso o respuestas grandes de forma incremental. Recuerda la cadena: ob_start() abre el buffer, ob_flush() libera su contenido al siguiente nivel y flush() los empuja hacia el cliente — y que el buffering del lado del servidor o la compresión gzip pueden seguir retrasando la entrega independientemente de lo que haga tu código PHP.