¿Cómo puedo imprimir un informe en Javascript mientras proceso el script PHP?

Estoy tratando de imprimir un informe en un área de texto usando Javascript o JQuery porque quiero mostrarle al usuario lo que está sucediendo mientras un script PHP se procesa en segundo plano durante algún tiempo, para que el usuario no piense que la aplicación se colgó.

Así que traté de actualizar automáticamente el área de texto usando setTimeout(...), y establecí el valor del informe en la sesión a través del script PHP mientras se procesa para obtener esa variable en el lado del cliente e imprimirla en el área de texto.

Aquí está el código que usé:

/*
 * The client side javascript function that updates the textArea value.
 */
function updateReport() {
    var reportValue = '<?php echo( $_SESSION[ 'report' ] ); ?>';
    document.forms[ 'start_send_form' ].elements[ 'reportTextArea' ].value = reportValue;

    setTimeout(function () {
        updateReport();
    }, 500);
}

El script php que llama el lado del cliente a través de una solicitud Ajax (JQuery):

<?php
    $report = "";

    for( $i = 0; $i < $number_of_items_to_process; $i++ ) {
        $report .= "- Processing a new item";
        $_SESSION[ 'report' ] = $report;    
        // .... Process some long code here.
    }
?>

Pero parece que updateReport() se ejecuta solo una vez cuando se llama por primera vez, luego se reanuda cuando finaliza el script PHP.

¿Puedes explicarme esto?

¿Y hay alguna manera de lograr lo que quiero?

---------------------------------- >> Actualización: el código que uso para tratar de obtener el valor actualizado para $_SESSION['informe'] del lado del servidor:

// 1. JavaScript :
function updateReport() {
    $.ajax({  
          url: "test2.php",  
          type: "POST",  
          cache: false,  
          success: function( returned_value ){
                var reportValue = $.trim( returned_value );
                alert(reportValue);  // All messages appear after PHP script ends.
          }
    });  

    setTimeout(function () {
        updateReport();
    }, 500);
}

// 2. test2.php(Script just made to get $_SESSION[ 'report' ]) :
<?php
    if ( !isset( $_SESSION ) ) session_start();
    echo( $_SESSION[ 'report' ] );
?>

preguntado el 12 de junio de 12 a las 10:06

3 Respuestas

Cuando visita un sitio php, por ejemplo, test.php, se traduce del servidor a html y se envía a su navegador web.

De modo que:

function updateReport() {
    var reportValue = '<?php echo( $_SESSION[ 'report' ] ); ?>';
    document.forms[ 'start_send_form' ].elements[ 'reportTextArea' ].value = reportValue;

    setTimeout(function () {
        updateReport();
    }, 500);
}

Estará en el navegador web (puede buscar esto en la herramienta de desarrollo firebug o chrome):

function updateReport() {
    var reportValue = '';
    document.forms[ 'start_send_form' ].elements[ 'reportTextArea' ].value = reportValue;

    setTimeout(function () {
        updateReport();
    }, 500);
}

Porque $_SESSION['report'] está vacío cuando visitas el sitio.

Cuando realiza su solicitud ajax, llama al código en el servidor. Cuando configura $_SESSION['report'], se configura en el servidor. Pero el cliente no obtiene esa información porque el cliente (su navegador web) no sabe qué es PHP. Simplemente establece una cadena vacía una y otra vez, porque solo obtuvo el html generado (del archivo PHP) EN LA SOLICITUD DE LA PÁGINA.

Debe realizar una solicitud Ajax adicional para obtener el nuevo valor de $_SESSION['informe'] para el cliente.

Respondido el 12 de junio de 12 a las 10:06

Gracias por la explicación clara. Estoy de acuerdo con usted, pero cuando obtengo $_SESSION['report'] a través de una solicitud Ajax del servidor, ¡lo toma después de que finaliza el script PHP! Cuando hago una alerta para el valor devuelto, todos los mensajes de alerta aparecen a la vez después de que el script PHP termina de procesarse. - Brad

Debe escribir un método PHP adicional que solo devuelva $SESSION['report'] y llamarlo. Luego le da el estado actual de la variable de informe. Aquí puede ver cómo puede llamar a un método PHP específico: stackoverflow.com/questions/2269307/… Solo tiene que escribir una acción/método getReport y whatYouWannaDo. Luego inicie la solicitud whatYouWannaDo Ajax y llame todos los x segundos al método PHP getReport a través de ajax hasta que se termine whatYouWannaDo. - SCBoy

Pero en las alertas, ¿se muestran los informes correctos? ¿Puede agregar su nuevo código a través de la edición en su publicación y escribir una breve descripción de lo que hizo? gracias. - SCBoy

Tu código me parece correcto... ¿Lo estás intentando en IE? (Una vez, una universidad tuvo un problema con ajax e IE). En caso de que sea así, ¿puedes probarlo en FF o Chrome... Pero esa es solo mi última idea, porque no puedo entender por qué no funciona... lo siento :( - SCBoy

De hecho, estoy usando Chrome. ¿Hay un subproceso único y multiproceso en PHP para variables? Lo que quiero decir es que si script1 ya está accediendo a una variable, entonces script2 no puede acceder a ella a menos que script1 finalice su trabajo. - Brad

Mientras puedas usar Transmisión HTTP para hacer esto, elegiría una forma un poco diferente de resolver este problema.

Dado que el procesamiento de todos los elementos llevará tiempo, debe realizarse mediante un proceso en segundo plano. En PHP puedes hacer esto con pcntl_fork().

En primer lugar, debe iniciar el procesamiento:

  1. verificar si el archivo foobar.pid existe
  2. si el archivo no está allí, créelo; de lo contrario, Goto 9
  3. elegir el siguiente elemento de la cola
  4. procesar el artículo
  5. if foobar.pid contiene "matar", entonces Goto 8
  6. si la cola está vacía: Goto 8
  7. Goto 3
  8. borrar archivo foobar.pid
  9. final

Esto haría que se verificara el proceso en segundo plano, ya existe uno de esos procesos. También le permitiría detener el bucle poniendo "matar" dentro del archivo.

Entonces... ¿qué pasa con los informes? Como parte del procesamiento, debe tener el servicio en segundo plano para escribir mensajes de estado en algunos status.txt archivo.

Este archivo puede ser leído por su secuencia de comandos XHR (lo que la gente de marketing llama - AJAX). Y el mismo código JavaScript puede comprobar si se ha realizado el procesamiento de todos los elementos (porque el foobar.pid el archivo se ha ido).

Respondido el 12 de junio de 12 a las 10:06

¿Qué tal probar esto:

  1. http://www.silverspider.com/2005/php-progress-bar/
  2. http://www.redips.net/javascript/ajax-progress-bar/ - este tiene una demostración funcional donde puedes ver las cargas de la barra de progreso...

Respondido el 12 de junio de 12 a las 10:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.