Brad
Brad

Reputation: 4547

How can i print a report in Javascript while processing PHP script?

I am trying to print a report in a textArea using Javascript or JQuery as i want to show user what is happening while a PHP script is processing in background for some time, so the user won't think the application hanged.

So i tried to automatically update the textArea using setTimeout(...), and set the report value in the session through the PHP script while it is processing to get that variable in the client side and print it in the textArea.

Here is the code i used :

/*
 * 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);
}

The php script that is called by the client side through an Ajax(JQuery) request :

<?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.
    }
?>

But it seems that updateReport() executes just once when it is first called, then resumes when the PHP script is done.

Can you explain this for me ?

And is there a way to accomplish what i want ?

---------------------------------- >> Update: The code i use trying to get the updated value for $_SESSION[ 'report' ] from server side :

// 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' ] );
?>

Upvotes: 0

Views: 1752

Answers (3)

tereško
tereško

Reputation: 58444

While you could use HTTP Streaming to do this, i would choose a bit different way to solve this issue.

Since processing of all the items will take time, it should be done by a background process. In PHP you can do this with pcntl_fork().

First, you have to start the processing:

  1. check if file foobar.pid exists
  2. if file is not there, create it, otherwise - goto 9
  3. pick next item from queue
  4. process the item
  5. if foobar.pid contains "kill", then goto 8
  6. if queue is empty: goto 8
  7. goto 3
  8. delete file foobar.pid
  9. end

This would cause the the background process to check, there already exist one such process. Also it would enable you to stop the loop, by putting "kill" inside the file.

So .. what about the reporting? As part of processing, you should have the background service to write status messages to some status.txt file.

This file then can be read by your XHR (what marketing people call - AJAX) script. And the same JavaScript code can check, if processing of all items has been done (because the foobar.pid file is gone).

Upvotes: 1

shadyyx
shadyyx

Reputation: 16055

What about trying this:

  1. http://www.silverspider.com/2005/php-progress-bar/
  2. http://www.redips.net/javascript/ajax-progress-bar/ - this one has a functional demo where You can see the progress bar loads...

Upvotes: 0

SCBoy
SCBoy

Reputation: 545

When your visit a php site for example test.php it gets translated from the server to html and gets send to your webbrowser.

So:

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

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

Will be in the webbrowser (you can look this up in the firebug or chrome dev tool):

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

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

Because $_SESSION['report'] is empty when you visit the site.

When you do your ajax request, you call code on the server. When you set $_SESSION['report'] it is set on the server. But the client doesn't get that information because the client (your webbrowser) doesn't know what PHP is. It just sets an empty string over and over again, because it only got the generated html (from the PHP file) AT THE PAGE REQUEST.

You have to make an extra Ajax request to get the new value from the $_SESSION['report'] to the client.

Upvotes: 2

Related Questions