PHP to get long running process progress dynamically

  Pi Ke        2012-06-04 07:29:37       59,997        10    

Frequently in web applications, we may have a request to the back end system which may trigger a long running process such as searching huge amount of data or a long running database process. Then the front end webpage may hang and wait for the process to be finished. During this process, if we can provide the user some information about the progress of the back end process, it may improve user experience. Unfortunately, in web applications, this seems not an easy task because web scripting languages don't support multithreading and HTTP is stateless.  We now can have AJAX to simulate real time process. Today we will use PHP+jQuery to simulate a process to get the progress of a long running process dynamically.

We need three files:

<?php
    //long_process.php
    for($i=1;$i<=10;$i++){
        session_start();
        $_SESSION["progress"]=$i;
        session_write_close();
        sleep(1);
    }
?>


The above code is the long_process.php which simulates the long running process, it actually has a for loop which will loop from 1 to 10 and will sleep for one second after each loop. The most important thing here is we use a session variable $_SESSION["progress"] to store the progress, also don't forget to use session_write_close() after each loop since session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.

One more file is progress.php

<?php
    //progress.php
    session_start();
    echo $_SESSION["progress"];
?>

what it does is very simple, just echo the progress to the client. This progress variable is the session variable updated in long_process.php.

One last PHP file:

<script type="text/javascript">
    //Start the long running process
    $.ajax({
        url: 'long_process.php',
        success: function(data) {
        }
    });
    //Start receiving progress
    function getProgress(){
        $.ajax({
            url: 'progress.php',
            success: function(data) {
                $("#progress").html(data);
                if(data<10){
                    getProgress();
                }
            }
        });
    }
    getProgress();
</script>
<div id="progress"></div>

The above code only contains the code inside(I omit rest of the code) and it actually is the entry of the simulation, it uses AJAX to send two requests to the server, one is to initialize the long running process and the other one is polling the server to get the progress. And after getting the progress, it updates the progress on the page.

Of course there are other ways to store the progress variable such as database or xml file etc.You can choose the way which you prefer or which you think is most efficient. Also, in addition to pure PHP code, you can have flash or Java applet to process and poll a long running process through TCP or UDP which are used by many websites.

If you have any better way other than this, you can share with us.

PHP  AJAX  DEMO  PROGRESS  LONG PROCESS 

       

  RELATED


  10 COMMENTS


Yongd [Reply]@ 2014-04-17 09:27:24

Thank you,this's very helpful to me!

Pi Ke [Reply]@ 2014-04-17 09:54:56

It's my pleasure

Alexander Avakov [Reply]@ 2015-02-17 06:03:56

Nice tutorial. Thank you!

alea123 [Reply]@ 2015-05-07 02:22:51

rly nice.. thank you!

samas [Reply]@ 2015-06-23 02:14:36

nice article, care to put up a complete working demo... full source code which can be easily adapted...?

verjas [Reply]@ 2015-08-21 02:51:53

I've just tested it on a project.

Works like a charm! Good job! 

Patrick [Reply]@ 2015-11-25 08:40:26

Very nice!!! Saved me hours!

Maksim Pol [Reply]@ 2016-01-10 02:55:16

It sometimes starts wrong. After page refresh, progress percent stays, but script working in background. If i make refresh again, then will run 2 scripts at one time. 

Anonymous [Reply]@ 2020-07-19 04:04:26

I had this similar issue.

I solved it by;

1. If() statement to prevent the long running script starting when the session variables already exist.

2. Unset() the session variables when the long script is complete and the last Ajax request has been called.

Maksim Pol [Reply]@ 2016-01-10 02:55:55

How it can be fixed? Anyway, thanks for the tutorial. :)



  RANDOM FUN

Tab and Space are mutual exclusive