2011-01-12 17 views
9

Tengo un script php que usa cURL y tarda unos 10-15 minutos en ejecutarse. Lo que hace, analiza aproximadamente 1000 páginas buscando coincidencias específicas y en todo el script tengo mensajes de diagnóstico repetidos, como "Pasar a la página siguiente", "Encontré una coincidencia", "Error al cargar la página" ... La forma en que funciona ahora (y la forma en que es normal) es que se ejecuta durante 10 minutos y solo luego escupe todos mis mensajes personalizados. Me gustaría poder mostrar esos mensajes a medida que ocurren, no cuando el script se termina de ejecutar. Estaba pensando que algo como AJAX lo haría, pero no estoy seguro de cómo funcionaría. Cualquier consejo es muy apreciado. Gracias.Mensajes de eco mientras el script php aún se ejecuta

+1

similares a [esta cuestión] (http://stackoverflow.com/questions/4481235/php-flush-ob-flush-not-working). – netcoder

+0

Otro caso simple sería ejecutar el script desde la línea de comandos, de esa manera obtendrá sus ecos en tiempo real. –

Respuesta

9

Entonces, esta es una publicación anterior, pero encontré una solución para esto. Como también tengo que hacer lo mismo, imprima cuando el script aún se está ejecutando. Ninguna respuesta de aquí ayudó. En primer lugar, estoy usando el servidor Win32 (producción) y XAMPP como local para las pruebas. Este ejemplo es solo una prueba de concepto y se puede modificar a su gusto.

<?php 
ob_implicit_flush(true); 
for($i=1; $i<=10; $i++){ 
echo "$i ...<br>"; 
for($k = 0; $k < 40000; $k++) echo ' '; 
sleep(1); 
} 
?> 

Entonces, abrimos el buffer de salida como implícito. Luego hacemos un ciclo de demostración para contar del 1 al 10 y mostrar los valores a medida que se procesan. El segundo bucle rellenará el búfer de los navegadores. Y finalmente, para verificar si todo está funcionando bien, dormimos durante 1 segundo. De lo contrario, el script se ejecutará demasiado rápido y no podríamos saber si logramos el objetivo. Espero que esto ayude!

6

Utilice flush para enviar inmediatamente la salida al navegador, enjuagando el búfer de salida.

echo "foo"; 
flush(); 
echo "bar"; 
flush(); 
+1

No se garantiza que la descarga funcione en todos los navegadores/plataformas/configuraciones – mrbinky3000

7

Puede crear una tabla de etapas.

El script PHP podría, en lugar de repetir el mensaje, almacenarlo en una tabla de base de datos (posiblemente tabla de memoria para el rendimiento).

Podrías periódicamente sondear un script PHP separado usando ajax, que consultaría la tabla, y devolvería cualquier mensaje nuevo al cliente.

+0

De acuerdo. La descarga no funcionará el 100% del tiempo. Ajax es necesario. – mrbinky3000

+0

¿No hay una solución tipo push (en lugar de sondeo)? – Richard

0

Básicamente, haga que el script escriba la salida HTML en un archivo de registro temporal. Luego use ajax para actualizar periódicamente el navegador del usuario final con el archivo de registro temporal. jQuery hará un trabajo rápido de esto.

Ajax es la única manera garantizada de que funcione en todos los navegadores. Aquí hay una cita de la página flush de PHP.

flush() puede no ser capaz de anular el esquema de amortiguación de su servidor web y no tiene efecto en ninguna de amortiguación del lado del cliente en el navegador. Tampoco afecta el espacio de usuario de PHP mecanismo de memoria de salida. Esto significa que tendrá que llamar tanto a ob_flush() y flush() para enjuagar los buffers de salida ob si los está usando.

+0

¿Qué pasa si hay 1000 usuarios accediendo a la página al mismo tiempo con diferentes parámetros? , necesitarás escribir 1000 archivos, no veo esto como una opción. –

+0

Puede crear fácilmente archivos temporales en PHP. Es básicamente lo mismo que 1000 usuarios INSERTAR cosas en una base de datos mysql. Diablos, uso, mysql. Simplemente almacene un registro en algún lugar y átelo a esa sesión si lo usa más de una persona. Tengo la sensación de que este es un script de back-end para ser utilizado por una sola persona. – mrbinky3000

+0

Tiene la sensación correcta. Voy a ser el único usuario. – pHelics

0

Suena como si tuviera output buffering encendido.

Llamando ob_end_flush() imprimirá lo que está actualmente en el búfer, y apague el búfer para el resto de la ejecución del script.

3

En realidad lo que buscas es algo así como flush y ob_flush, sin embargo, tenga en cuenta que hay una gran cantidad de factores que pueden impedir su salida de ser flush'd como sucede.

De la documentación flush se obtendrá:

varios servidores, especialmente en Win32, seguirá siendo amortiguar la salida de la secuencia de comandos hasta que termina antes de transmitir los resultados al navegador.

Los módulos de servidor para Apache como mod_gzip pueden hacer un búfer propio que hará que flush() no provoque que los datos se envíen inmediatamente al cliente.

+0

Hiciste un buen punto, hasta que el script esté listo, estoy trabajando en él en la plataforma Win32, luego lo pondré en Unix – pHelics

0

usted podría utilizar tanto flush y ob_flush, recordando a establecer el encabezado de tipo de contenido:

<?php 
header('Content-type: text/html; charset=utf-8'); 
for($i = 0 ; $i < 10 ; $i++){ 
    echo $i . '<br>'; 
    flush(); 
    ob_flush(); 
    sleep(1); 
} 

Fuente: dermeister nota en php.net ob_flush página.

probado en Firefox y Chrome 42,0 46,0

1

estoy usando el @ob_flush() después de cada echo. En este ejemplo PHP_EOL crea una nueva línea después $string

function output($string){ 
    echo $string.PHP_EOL; 
    @ob_flush(); 
} 
Cuestiones relacionadas