2010-11-16 15 views
61

¿Cuál es la diferencia entre ob_flush() y flush() y por qué debo llamar a ambos?PHP buffer ob_flush() vs. flush()

El ob_flush() reference dice:

Esta función enviará el contenido de la memoria intermedia de salida (si lo hay).

El flush() reference dice:

Vacía los buffers de escritura de PHP y cualquiera que sea el motor que PHP está usando (CGI, el servidor web, etc).

Sin embargo, continúa diciendo:

[que] puede no ser capaz de eliminar el esquema de almacenamiento temporal de su servidor web ...

Por lo tanto, me parece que lo que pude solo use ob_flush() todo el tiempo. Sin embargo, obtengo resultados extraños cuando hago eso. ¿Podría alguien explicar en términos simples qué está pasando aquí?

Respuesta

62

ob_flush envía un búfer iniciado por la aplicación. Puede haber múltiples anidados ob_start() en cualquier script PHP. ob_flush pasa el contenido actual a la capa superior.

PHP mismo podría (a su propia discreción) salida de búfer. Esto depende del back-end. Pero generalmente FastCGI tiene un buffer de socket por sí mismo. Por lo tanto, es necesario invocar también flush() para enviar el contenido actual al servidor web.

Y ahora el servidor web podría implementar otro esquema de almacenamiento en búfer (mod_deflate o filtro de contenido), sobre el que no tiene influencia. Pero esto es raro, ya que debe configurarse específicamente.

De todos modos, use ambos.

+6

Use ob_flush y flush y úselos en ese orden. – Robino

+12

El detalle importante que falta en esta respuesta es la opción de configuración ['output_buffering'] (http://www.php.net/manual/en/outcontrol.configuration.php#ini.output-buffering), cuyo valor predeterminado en producción las versiones de php.ini son 4096. Eso significa que cuando se inicia cualquier script de PHP, los primeros 4096 bytes de salida se almacenan en búfer (en un búfer descargable con 'ob_flush()'). Es por eso que es necesario usar 'ob_flush()' así como 'flush()'. Deshabilitar 'output_buffering' via php.ini o llamar' ob_end_clean() 'o' ob_end_flush() 'al inicio del script elimina esta necesidad. –

26

ob_flush vuelca buffers de salida se ha creado con una función como ob_start

flush rubores búfer de salida del propio script PHP a su llamador

10

supongo que esto es en relación a su previous question. La gran ventaja de utilizar el buffer de salida es cuando se usa junto con la compresión de datos. Si no está usando ob_gzhandler, hay poco que ganar. flush solo solo confirmará los datos de salida que aún estén en el servidor. Con ob_start y sus homólogos ob_flush, ob_end_clean y ob_end_flush, lo que se espera de ser comprimido (un vistazo a flush y ob_flush como una referencia a diferentes cubos - ob envía datos a flush, flush envía datos al navegador - no puede ser exacta, pero esa es la idea) será envuelto y enviado al cliente.

+0

Gracias, la analogía del cubo es un buen ejemplo. – Ben

18

ob_flush() es una descarga de alto nivel. Vacía los búferes de alto nivel y pone todo el contenido en los búferes internos de bajo nivel listos para enviar.

  • Tenga en cuenta que la familia de funciones ob_ crear pilas de tampones, por lo que acaba de escribir a ciegas ob_flush() todas partes es, en efecto va a dar "resultados extraños" si el código fue escrito para tomar ventaja de este apilamiento.

flush() es una descarga de bajo nivel, indicando a PHP que elimine sus búfers de datos internos de bajo nivel.

Debajo de eso, habrá memorias intermedias de socket; debajo de eso, hay búferes de capa de red. Y, en el nivel más bajo, la fila de electrones baja por el cable de datos.