Quiero retrasar algunas salidas usando sleep() o usleep().
Eso funciona muy bien en la terminal, pero cuando ejecuto el script en un servidor que tiene habilitado gzip, la salida se almacenará en el búfer por completo y luego se comprimirá y luego se enviará al navegador.

¿Hay alguna manera de forzar al servidor (Apache) a no almacenar el script en el búfer?
o para forzar al servidor a borrar el búfer,
¿ o para averiguar en PHP si Apache comprime o no el material?
Entonces podría deshabilitar todos los retrasos, lo que sería útil si no puedo forzar la salida directa ...

EDITAR: Lamentablemente, no puedo editar ningún archivo de configuración, el comportamiento debe ser coherente en muchas configuraciones de php diferentes.

1
mvmoay 22 mar. 2017 a las 17:54

2 respuestas

La mejor respuesta

Después de buscar y probar un poco, descubrí varias cosas.

1) Puede haber compresión gzip que se ejecuta a través de la biblioteca zlib. Esto se puede desactivar en tiempo de ejecución:

ini_set('zlib.output_compression', false);

2) Además, puede haber gzipping aplicado a través de un módulo Apache. No es posible ver si esto sucederá o no después de la ejecución del código, pero hay una forma bastante confiable de romperlo:

header("Content-Encoding: none");

Esto no es compatible con el estándar, pero obliga a Apache a pensar que el contenido proporcionado posiblemente no se puede comprimir. Entonces no saltará.

Puede haber muchas otras situaciones (como nginx u otra extensión de gzipping, etc.), pero en la mayoría de los casos, esta combinación de trucos funcionará:

// disable zlib
ini_set('zlib.output_compression', false);
// Force termination of all instantiated buffers
while (@ob_end_flush());

// prevent apache from gzipping
header("Content-Encoding: none");

// prevent the browsers from showing a cached version before showing the new one
header('Cache-Control: no-cache');

// Start the output to enable buffering 
header('Content-Type: text/html; charset=utf-8' );

// Push the beginning of the page to the browser
ob_flush();
flush();

// Do stuff here.

Espero que esto ayude a alguien ...

0
mvmoay 23 mar. 2017 a las 11:17

EDITAR debido a la información adicional

Bien, entonces digo: No puede tener una automatización confiable.
Puede hacer un encabezado curl a un pequeño archivo php en el mismo dominio (empty.php que "prueba" de echo) para ver si se envía con compresión antes de hacer la salida.
Pero esto agrega demora al primer byte en su script. La solución más fácil sería un archivo de configuración para su secuencia de comandos que le permita al administrador de la web decir: gzip habilitado o deshabilitado antes de implementar su secuencia de comandos en producción.

Debido a que gzip se puede usar en php, salida del servidor, proxies, etc. Y cualquier administrador consciente de SEO tiene GZIP habilitado por defecto porque le da puntos de bonificación en google. Entonces, en realidad, sugeriría abandonar los durmientes y usar múltiples solicitudes ajax para obtener la información que lleva más tiempo preparar o usar websockets para proporcionar su información si realmente necesita la espera.

Debe excluir su archivo del almacenamiento en caché a través del archivo de configuración de apache.

Ver: Para php flush - cómo ¿Deshabilitar gzip para un archivo específico?

Pon esto en tu httpd.conf

# exclude certain page requests (e.g. for requesting getMyFile.php?action=getFile&id=3 as non-compressed)
SetEnvIfNoCase Request_URI getMyFile\.php$ no-gzip dont-vary

Si tiene archivos que usan parámetros get, deje el signo $ al final de getMyFile\.php

1
Community 23 may. 2017 a las 12:25