2011-08-24 22 views
6

Hemos estado utilizando php flush para "poner en blanco" una página inmediatamente tan pronto como se hace clic, y también para enviar la navegación y los componentes principales de la página para que la página aparezca casi al instante , aunque a veces el contenido puede tardar mucho tiempo en cargarse.PHP flush detuvo el lavado en IIS7.5

Esto ha funcionado muy bien.

Recientemente hemos actualizado de IIS 7.0 a 7.5 y ahora el enjuague no funciona. Al investigar el problema, hemos desactivado la compresión de archivos estáticos y dinámicos. También hemos desactivado el almacenamiento en caché de resultados.

También tenemos la compresión zlib desactivada y el buffer de salida desactivado en php.ini.

Con el fin de probar el problema que tenemos el siguiente script

@ini_set("output_buffering", "Off"); 
@ini_set('implicit_flush', 1); 
@ini_set('zlib.output_compression', 0); 

ob_start(); 

echo "starting...<br/>\n"; 
for($i = 0; $i < 5; $i++) { 
    print "$i<br/>\n"; 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
    sleep(2); 
} 
print "DONE!<br/>\n"; 

El browser muestra el estado de carga (sea lo que sea en cualquier navegador, en el IE se ve como un gif animado Ajax, en Firefox la la pestaña dirá "Conectando ...") durante 10 segundos, y de repente aparecerá todo el resultado.

Hemos probado varias combinaciones de color y ob_flush y ob_end_flush basadas en preguntas similares en este sitio. Ninguno de ellos funciona. ¿Hay alguna forma de hacer que IIS/PHP limpie los datos?

Respuesta

7

debe establecer el valor ResponseBufferLimit del controlador deseado a un número suficiente como para realmente ras baja. Recomiendo usar 0 ya que evita que IIS haga algo más que pasar lo que se envía desde su script PHP. Puede utilizar la línea de comandos para configurar el ResponseBufferLimit a 0 para el manejador de php (sólo cambia “Nombre” para el nombre del controlador que desea actualizar por ejemplo PHP53_via_FastCGI):

appcmd.exe set config /section:handlers "/[name='NAME'].ResponseBufferLimit:0" 

Alternativamente, se puede editar la aplicación Host.config directamente y agrega un atributo ResponseBufferLimit al elemento XML.

3

Lo que hago es que utilizo la siguiente función:

function flush_buffers(){ 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
} 

Así que en su código:

ob_start(); 
flush_buffers(); 

echo "starting...<br/>\n"; 
for($i = 0; $i < 5; $i++) { 
    print "$i<br/>\n"; 
    flush_buffers(); 
    sleep(2); 
} 

debería funcionar sin problemas :-)


Aquí está algún código de trabajo (con el conjunto correcto Content-Type):
DEMO
CODE

<?php 
header("Content-Type: text/html; charset=utf-8"); 
function flush_buffers(){ 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
} 

ob_start(); 
flush_buffers(); 
echo "starting...<br/>\n"; 
for($i = 0; $i < 60; $i++) { 
    flush_buffers(); 
    print "$i<br/>\n"; 
    flush_buffers(); 
    sleep(2); 
} 

flush_buffers(); 

print "DONE!<br/>\n"; 
?> 
+0

Esto funcionó. Desmontarlo pieza por pieza para ver cuál es la clave ... –

+0

@Jeff, la demostración debería ayudar un poco :-) – Neal

+1

Parece que la clave es el tipo de contenido: text/html; charset = utf-8. Agregar esto como un encabezado también funciona. En particular, parece que el juego de caracteres = utf-8 es lo que lo hace funcionar. –

1

Es hasta el servidor web si decide naggle el contenido o enviarlo a través de la codificación fragmentada. Entonces, aunque PHP puede preguntar al servidor para enviar datos al cliente, no puede obligar al servidor a utilizar la codificación fragmentada.

This article sugiere que explícitamente necesite establecer la codificación de transferencia para IIS (vea el bit sobre ISAPI) para enviar datos al servidor; puede intentar lo mismo en su secuencia de comandos.

IME, la mayoría de los escenarios en que esto sea un problema se puede resolver mejor ....

register_shutdown_function('do_slow_stuff'); 
....generate html content.... 
exit; // closes stdin/stdout, but shutdown fn will still be called 

function do_slow_stuff() 
{ 
    .... 
} 
4

Introduzca el siguiente comando como administrador en Powershell:

C:\Windows\System32\inetsrv> .\appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0" 

Resultados esperados:

La configuración aplicada cambia a la sección "sistema".WebServer/manipuladores" para "Máquina/WEBROOT/APPHOST" en comm configuración de ruta que "MÁQUINA/WEBROOT/APPHOST"

Para más antecedentes, echar un vistazo a: http://www.coastrd.com/cgioniis7

Básicamente, necesitamos . FastCGI para contar a su vez de su ResponseBufferLimit Esto no se puede hacer a través de la consola de administración de IIS (sólo el 7,5 verificado)

23

Hay otra manera de establecer el límite de respuesta mediante el Administrador de IIS:

  1. En la página principal del servidor, en "Administración", seleccione "Editor de configuración";
  2. en "Sección", ingrese 'system.webServer/handlers';
  3. al lado de "(Colección)" haga clic en "..." O marque el elemento "(Colección)" y, en "Acciones" und '(Colección)' Elemento, haga clic en "Editar elementos";
  4. desplácese hacia abajo hasta encontrar su versión de PHP en "Nombre";
  5. en la parte inferior, las Propiedades se muestran y se pueden editar manualmente, incluido responseBufferLimit, que se debe establecer en 0 para que flush() funcione.

El gran Pro es que puedes editar las propiedades de todo, no solo PHP sino también puedes trabajar con diferentes versiones (o incluso instalaciones de la misma versión) de PHP.

HTH

+2

+1 excelente! Esta es la primera vez que veo una solución para establecer el responsebufferlimit a través del administrador de IIS. – Rich

+0

Esta es la mejor soution. Gracias –

2

Llego un poco tarde a la fiesta, pero pensé que agregaría cómo hacerlo con web.config.

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
     <!--- other stuff here ---> 
     <handlers> 
      <remove name="ISAPI-dll" /> 
      <add name="ISAPI-dll" path="*.dll" verb="*" type="" modules="IsapiModule" scriptProcessor="" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
     </handlers> 
    </system.webServer> 
</configuration> 
0

Ésta es otra manera de hacer esto con web.config (@ método de Jules no funcionaba para mí con IIS 8.0). Por supuesto, desearía reemplazar las versiones y rutas de PHP con las que realmente están en su máquina.

¡Esto permite el uso de eventos enviados por el servidor!

<configuration> 
    <system.webServer> 
     <handlers> 
      <remove name="PHP53_via_FastCGI" /> 
      <remove name="PHP54_via_FastCGI" /> 
      <remove name="PHP55_via_FastCGI" /> 
      <add name="PHP53_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.3\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
      <add name="PHP54_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
      <add name="PHP55_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.5\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
     </handlers> 
    </system.webServer> 
</configuration> 
Cuestiones relacionadas