Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting progress of PHP script called by jQuery post

I want to periodically check the status of a php script and display it on the browser. Here is the jQuery that is used to post.

$(document).ready(function() {
      $("#tempbut").click(function(event){
           $('#loader').show();
           $('#mainarea').hide('fast');

          $.post(
           "template.php",
           {
                guide : $('#guide').val(),
                title : $('#title').val()
           },
            function(data) {
                $('#mainarea').empty();
                $('#loader').fadeOut('slow');
                $('#mainarea').append(data);
                $('#mainarea').show('slow');
             }

          );
      });
   });

In the PHP Script (not posted), I echo statements such as "Building request...", "Sending request..." to inform the user of the progress. If I were not using jQuery post, I would be able to show the status using flush() and obflush() after every echo. Perhaps it is because the callback waits for the script to fully execute before outputting?

Is there a way to modify the existing jQuery .post to do this? I see a few examples using .ajax, but not .post.

If .ajax is the only way to do this how would I modify this code?

Thanks!

EDIT: Got it running! Hopefully someone will find this helpful. (you can delete console.log)

test.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>TEST</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1" />
    <script src="http://code.jquery.com/jquery-2.1.0.js"></script>
    <script>
        $.ajax({
            url: "test.php",
            xhrFields: {
                onprogress: function(e) {
                    console.log(e.target.responseText)
                    $("body").html(e.target.responseText)
                    if (e.lengthComputable) {
                        console.log(e.loaded / e.total * 100 + '%');
                    }
                }
            },
            success: function(text) {
                    console.log(text)
                    $("body").html(text+"<h1>done!</h1>")
            }
        });
    </script>
</head>
<body>
<div id="derp">TEST!</div>

</body>
</html>

test.php

<?php

for($i = 0; $i<20 ; $i++){
    sleep(1);
    echo $i."</br>";
    flush();
    ob_flush(); 
}
?>
like image 465
rawrzors Avatar asked Oct 21 '22 13:10

rawrzors


1 Answers

post is a shortcut for ajax(type:post) , nothing different .

to get progress report there are some ways.the simplest that come to my mine right now is to make 2 ajax request 1 to the same page to run your php script and store the status in session and another to a diffrent page that read the status from session and prints it for user .

UPDATE:

ohhhh my bad session doesn't get written down untill the php script is finished . you can try writing the status to a file and reading from it like this :

task.php

for ($i = 0; $i < 10; $i++) {
    echo($i . "<br/>");
    file_put_contents('progress', $i);
    sleep(2);
}

progress.php

if (file_exists('progress') && is_readable('progress'))
    echo file_get_contents('progress');
else
    echo(-1);

and the script:

<script>
    $(document).ready(function () {
        task();
        getProgress();
    });
    function task() {
        $.ajax({
            url: 'http://localhost/test/progress/task.php',
            success: function (data) {
                console.log('Task is over :' + data);
            }
        });
    }
    function getProgress() {
        $.ajax({
            url: 'http://localhost/test/progress/progress.php',
            success: function (data) {
                data = parseInt(data);
                if (data != 9) {
                    console.log('progress :' + data);
                    setTimeout(function () {
                        getProgress();
                    }, 1000);
                }
            }
        });
    }
</script>

BUT is a multi user environment this will cause problems.

so the best thing you can do is store the status in one of these :

  • use a database
  • use memcache
  • use APC
like image 126
Exlord Avatar answered Oct 23 '22 03:10

Exlord