php nginx flush

PHP Flush que funciona... incluso en Nginx



(8)

¿Es posible hacer eco cada vez que se ejecuta el ciclo? Por ejemplo:

foreach(range(1,9) as $n){ echo $n."/n"; sleep(1); }

En lugar de imprimir todo cuando termina el ciclo, me gustaría verlo imprimiendo cada resultado por vez.



Descubrí que puedes configurar:

header("Content-Encoding:identity");

en su script php para desactivar nginx gzipping sin tener que modificar el nginx.conf


La forma más fácil de eliminar el almacenamiento en búfer de nginx es emitiendo un encabezado:

header(''X-Accel-Buffering: no'');

Esto elimina tanto proxy_buffering como (si tiene nginx> = 1.5.6), fastcgi_buffering . El bit fastcgi es crucial si estás usando php-fpm. El encabezado también es mucho más conveniente de hacer según sea necesario.

Documentos sobre X-Accel-Buffering Docs en fastcgi_buffering


No quería tener que apagar gzip para todo el servidor o un directorio completo, solo para algunos scripts, en algunos casos específicos.

Todo lo que necesitas es esto antes de que cualquier cosa se repita:

header(''Content-Encoding: none;'');

Luego haz el color como siempre:

ob_end_flush(); flush();

Nginx parece darse cuenta de que la codificación se ha desactivado y no gzip.


Puede lograr esto descargando el búfer de salida en el medio del bucle.

Ejemplo:

ob_start(); foreach(range(1,9) as $n){ echo $n."/n"; ob_flush(); flush(); sleep(1); }

Tenga en cuenta que su configuración php.ini puede afectar si esto funcionará o no si tiene activada la compresión zlib


SOLUCIÓN FINAL

Entonces eso es lo que descubrí:

Flush no funcionaría bajo mod_gzip de Apache o gzip de Nginx porque, lógicamente, está comprimiendo gzip el contenido, y para hacerlo debe almacenar el contenido para gzip. Cualquier tipo de servidor web gzipping afectaría esto. En resumen, en el lado del servidor, tenemos que desactivar gzip y disminuir el tamaño del búfer fastcgi. Asi que:

  • En php.ini:

    . output_buffering = Off

    . zlib.output_compression = desactivado

  • En nginx.conf:

    . gzip apagado;

    . proxy_buffering off;

También tenga estas líneas a mano, especialmente si no tiene acceso a php.ini:

  • @ini_set (''zlib.output_compression'', 0);

  • @ini_set (''implicit_flush'', 1);

  • @ob_end_clean ();

  • set_time_limit (0);

Por último, si lo tiene, comente el siguiente código:

  • ob_start (''ob_gzhandler'');

  • ob_flush ();

Código de prueba de PHP:

ob_implicit_flush(1); for($i=0; $i<10; $i++){ echo $i; //this is for the buffer achieve the minimum size in order to flush data echo str_repeat('' '',1024*64); sleep(1); }

Relacionado:


Solución fácil en el servidor nginx:

fastcgi_keep_conn on; # < solution proxy_buffering off; gzip off;


Tuve un problema gzip proveniente de mi motor php-fpm. este código es el único que funciona para mí:

function myEchoFlush_init() { ini_set(''zlib.output_compression'', 0); ini_set(''output_buffering'', ''Off''); ini_set(''output_handler'', ''''); ini_set(''implicit_flush'', 1); ob_implicit_flush(1); ob_end_clean(); header(''Content-Encoding: none;''); } function myEchoFlush($str) { echo $str . str_repeat('' '', ini_get(''output_buffering'') * 4) . "<br>/n"; }

Esta es mi función de prueba: comprueba max_execution_time:

public function timeOut($time = 1, $max = 0) { myEchoFlush_init(); if ($max) ini_set(''max_execution_time'', $max); myEchoFlush("Starting infinite loop for $time seconds. It shouldn''t exceed : " . (ini_get(''max_execution_time''))); $start = microtime(true); $lastTick = 1; while (true) { $tick = ceil(microtime(true) - $start); if ($tick > $lastTick) { myEchoFlush(microtime(true) - $start); $lastTick = $tick; } if ($tick > $time) break; } echo "OK"; }