PHP función que muestre su propio progreso

radykal

Buenas,

estoy con el desarrollo de una Web usando Zend Framework 2 pero la pregunta en sí no va relacionada con el framework.

Tengo una función que recorre una serie de directorios con subdirectorios e imágenes, vas procesando una serie de información y guardando la estructura en una base de datos para el sistema de ecommerce, el proceso en si tarda unos cuantos segundos dependiendo de cuantos subdirectorios e imágenes haya y me gustaría mostrar algún tipo de información en tiempo real al usuario, tipo un log que se vaya rellenando conforme se vaya ejecutando y no tengo ni idea de por donde empezar.

MrTurbo

Así rápido no puedes hacer nada directamente desde PHP. Yo haría algo como que el propio php escriba en un fichero su progreso y luego tu desde el frontend vas leyendo cada segundo o medio segundo con un setTimeout con un ajax a ese fichero en el que tienes el progreso, y según lo que tengas en ese fichero (puedes hacer que se escriba un nº del 0 al 100) pues muestras ese progreso.

Saludos!

1 1 respuesta
elkaoD

#2 me has inspirado con eso de "no se puede" (es una variante de "no hay cojones" xD).

El problema de que el propio PHP escriba su progreso es que tienes un hilo ocupado tontamente, y otro para las respuestas al frontend.

Por dar una idea, ¿no se podría usar long polling? Buscad "php long polling" en Google.

En cualquier caso es una mala idea de ambas formas. Lo ideal sería usar websockets... o al menos no usar PHP por lo de monolítico y mono-hilo.

13500

#1 esa funcion que va guardando la estructura en una base de datos, se trata de un bucle? de ese modo podrias escribir codigo jquery dentro del PHP.

Me explico. Suponiendo que pudieras detectar por php cada salto de directorio o subdirectorio, podrias hacer una llamada a la funcion .ajax de un jquery para que fuera rellenando una barra previamente creada con el nº total de subdirectorios.

radykal

Gracias por las respuestas, creo que lo haré tirando de base de datos y ajax refrescando cada X tiempo.

Lanzaré el proceso asíncronamente, le asignaré un id y en la base de datos crearé una tabla para su log. Luego via AJAX iré refrescando la página cada 10 segundos o asi con los resultados de consultar a la base de datos por el log de este proceso.

Gantorys

Puedes guardar el resultado en una variable de sesión y después recibirla por AJAX cada "x" segundos.

Lo malo que un proceso de PHP en ejecucion bloquea todos los accesos a su sesión (con el sistema por defecto), echa un ojo a esto: http://stackoverflow.com/questions/12401358/why-should-session-write-close-be-used-in-long-polling

xMarston

Creo que quieres algo así:

<?php
header("Content-Type: text/html"); // Set Content-Type
while (@ob_end_flush()); // Flush and disable output buffers
while ($a++ < 5) {
  $b = 0;
  while ($b++ < 1015) {
    echo "H";
    //flush(); // In fact because there is no significant delay, you should not flush here.
  }
  echo "<br><br>\n";
  flush(); // Flush output
  sleep(1);
}
?>

En este caso está puesto con un sleep para ver el efecto. Al hacer flush, te muestra la salida correspondiente aunque no haya acabado con la ejecución del script.

PD: Está sacado de stackoverflow, por ello los comentarios en inglés.

Usuarios habituales

  • xMarston
  • Gantorys
  • radykal
  • 13500
  • elkaoD
  • MrTurbo