Nota para los usuarios de mod_fcgid (utilice bajo su propio riesgo).
Solución rápida
La respuesta aceptada de Joeri Sebrechts es de hecho funcional. Sin embargo, si usa mod_fcgid, es posible que esta solución no funcione por sí sola. En otras palabras, cuando se llama a la función de descarga , la conexión con el cliente no se cierra.
El FcgidOutputBufferSize
parámetro de configuración de mod_fcgid puede ser el culpable. He encontrado este consejo en:
- esta respuesta de Travers Carter y
- esta publicación de blog de Seumas Mackinnon .
Después de leer lo anterior, puede llegar a la conclusión de que una solución rápida sería agregar la línea (consulte "Ejemplo de host virtual" al final):
FcgidOutputBufferSize 0
en su archivo de configuración de Apache (por ejemplo, httpd.conf), su archivo de configuración de FCGI (por ejemplo, fcgid.conf) o en su archivo de hosts virtuales (por ejemplo, httpd-vhosts.conf).
En (1) arriba, se menciona una variable llamada "OutputBufferSize". Este es el nombre antiguo del FcgidOutputBufferSize
mencionado en (2) (consulte las notas de actualización en la página web de Apache para mod_fcgid ).
Detalles y una segunda solución
La solución anterior deshabilita el almacenamiento en búfer realizado por mod_fcgid para todo el servidor o para un host virtual específico. Esto puede provocar una penalización del rendimiento de su sitio web. Por otro lado, este puede no ser el caso, ya que PHP realiza el almacenamiento en búfer por sí solo.
En caso de que no desee deshabilitar el almacenamiento en búfer de mod_fcgid , existe otra solución ... puede forzar el vaciado de este búfer .
El siguiente código hace precisamente eso basándose en la solución propuesta por Joeri Sebrechts:
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
echo(str_repeat(' ', 65537)); // [+] Line added: Fill up mod_fcgi's buffer.
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
// Do processing here
sleep(30);
echo('Text user will never see');
?>
Lo que la línea de código agregada esencialmente hace es llenar el búfer de mod_fcgi , forzándolo así a vaciarse. Se eligió el número "65537" porque el valor predeterminado de la FcgidOutputBufferSize
variable es "65536", como se menciona en la página web de Apache para la directiva correspondiente . Por lo tanto, es posible que deba ajustar este valor en consecuencia si se establece otro valor en su entorno.
Mi entorno
- WampServer 2.5
- Apache 2.4.9
- PHP 5.5.19 VC11, x86, no seguro para subprocesos
- mod_fcgid / 2.3.9
- Windows 7 Professional x64
Ejemplo de host virtual
<VirtualHost *:80>
DocumentRoot "d:/wamp/www/example"
ServerName example.local
FcgidOutputBufferSize 0
<Directory "d:/wamp/www/example">
Require all granted
</Directory>
</VirtualHost>