usar resueltos para listos instalar httpd ejercicios ejecutar configurar conf como codigos archivo abrir php apache output-buffering

resueltos - Evite el almacenamiento en búfer de salida con PHP y Apache



configurar php en apache linux (3)

Tengo un script PHP que envía una gran cantidad de registros, y quiero vaciar cada registro tan pronto como esté disponible: el cliente puede procesar cada registro a medida que llega, no necesita esperar toda la respuesta. Me doy cuenta de que lleva un poco más de tiempo la transferencia completa, ya que debe enviarse en múltiples paquetes, pero aún permite que el cliente empiece a trabajar más rápido.

He probado todas las diferentes funciones flush() y ob_flush() pero nada parece ayudar a que los datos realmente se envíen a través de la línea antes de que la página finalice. Confirmé que no es el navegador web porque lo probé usando telnet.


La única solución que funcionó para mí fue establecer la directiva output_buffering en php.ini en "Off". No quería hacer esto para todo el servidor, solo este recurso específico. Normalmente, puede usar ini_set desde el script PHP, pero por cualquier razón, php no permite que output_buffering se establezca de esta manera (consulte el manual de php ).

Bueno, resulta que si está utilizando Apache, puede establecer algunas directivas php ini (incluyendo output_buffering ) desde su configuración de servidor, incluido un archivo .htaccess. Así que usé lo siguiente en un archivo .htaccess para desactivar el output_buffering solo para ese archivo:

<Files "q.php"> php_value output_buffering Off </Files>

Y luego, en mi configuración de servidor estático, solo necesitaba AllowOverride Options=php_value (o un martillo más grande, como AllowOverride All ) para que eso se permitiera en un archivo .htaccess.


No mencionas el servidor web que estás utilizando, pero voy a dar un paso aquí y adivinar Apache2. Golpeo casi la misma cosa que describes. Estaba intentando que mi script cgi transmitiera la información, ya que estaba lista, en lugar de almacenar todo el contenido. Trabajó jiffy en curl, etc., pero se almacenó en un navegador (prácticamente cualquier navegador), lo que al menos fue enloquecedor. Pasé por los pasos exactos que describes. La resolución en mi caso fue modificar el archivo de configuración de sites-enabled/terrifico.com en Apache2 (la línea en cuestión comienza con

SetEnvIfNoCase

(Puedes ignorar lo que está arriba y abajo de esa línea, solo lo estoy mostrando para referencia de dónde lo coloqué).

<VirtualHost *:80> ServerAdmin webmaster@localhost ServerName test.terrifico.com ServerAlias test.terrifico.com SetEnvIfNoCase Request_URI /.cgi$ no-gzip dont-vary DocumentRoot /var/www/test.terrifico.com

Al mirar el tráfico de la red yendo y viniendo, finalmente caí en la cuenta de que el navegador anunciaba que aceptaba la deflación para cualquier cosa (eso era texto). Esa era la diferencia entre el navegador y el curl, por ejemplo. El bit más destacado fue

Aceptar-Codificación: gzip, desinflar, sdch

Hubo un poco sobre chunking , pero eso no impactó este problema en particular. Por lo tanto, el navegador solicitaba la mod_deflate de mod_deflate , lo que me mod_deflate bytes cuidadosamente, ya que los obtuve en mi script cgi. Podrías cambiarlo en el navegador, pero parecía más sensato cambiarlo en el servidor una vez para las obras.

Quizás esto ayude.


Para desactivar el buffering de salida en tiempo de ejecución en PHP sin cambiar php.ini o tener un archivo .htaccess , simplemente use ob_end_flush() u ob_end_clean() al comienzo del script. Por ejemplo:

Esto debería salir sin almacenamiento en búfer:

<?php ob_end_clean(); for ($i = 0; $i < 5; $i++) { echo "$i/n"; flush(); usleep(0.5e6); }

Esto produce un buffering (todo a la vez) si output_buffering está output_buffering , independientemente de la llamada flush() :

<?php for ($i = 0; $i < 5; $i++) { echo "$i/n"; flush(); usleep(0.5e6); }

A pesar de su nombre, ob_implicit_flush llama flush() , not ob_flush() , implícitamente después de cada salida. Esto puede ser útil en esta instancia después de cerrar el buffer de salida al principio:

<?php ob_end_clean(); // disable output buffer ob_implicit_flush(); // call flush() automatically after every output for ($i = 0; $i < 5; $i++) { echo "$i/n"; usleep(0.5e6); }

Esto arregla el lado de PHP. Puede haber algo más pasando con mod_deflate o similar (ver la respuesta de Ted Collins), y he observado que Firefox necesita al menos 1024 bytes antes de que comience a producir nada.