开发者

PHP + jQuery Synchronization problem

I'm using jQuery + PHP on my website and I want to do something like this:

To simplify things I've got a page with 2 buttons () and according to which I click I want to start a script in background (php script) so I do a simple thing with jquery:

$("#button1").click(function(){
    $.post("script.php", {val:"but1"}, function(result){
        alert(result); // I want something with the result
    });
});

$("#button2").click(function(){
    $.post("script.php", {val:"but2"}, function(result){
        alert(result);
    });
});

and in the script.php I've got a simple if statement deciding what I should do.

In the php script I'm downloading a file and I want to create a progress bar of the file download. The php script would return me values (echo percentage; flush();) in some time interval.

And here comes the problem - when I echo those percentage values and flush it refreshes it "just in php" but the jquery waits until the script is finished anyway. Is there a way to get those values as they appear (after flush) or is there a completely other approach to this? I can't think of anything开发者_如何学编程 else right now, maybe I shouldn't be using jquery at all.

Thanks for the help.


You can store the progress in a text file or DB while running the script and then have another file get the result via AJAX calls.

JS/HTML

<script>
$(function() {
    var id;
    var timeoutLength = 1000;

    $("#button1").click(function() {
        $("#result").html("");

        // Create unique identifier
        id = (new Date().getTime()) + "-" + Math.floor(Math.random()*100);
        $.get("script.php", {id: id}, function(result){
            $("#result").html(result);
        });

        setTimeout(checkProgress, timeoutLength);
    });

    function checkProgress() {
        $.get("script.php", {progress: true, id: id}, function(data) {
            prog = parseInt(data);
            // Display progress bar
            if(prog < 100) {
                $("#progress").css({ display: 'block', width: prog });
                $("#progress").html(prog + "%");

                setTimeout(checkProgress, timeoutLength);
            } else {
                $("#progress").css('display', 'none');
            }
        });
    }
})
</script>
<button id="button1">Click</button>
<div id="progress" style="background: green"></div>
<div id="result"></div>

script.php

<?php

function getProgress($file) {
    return (file_exists($file)) ? file_get_contents($file) : 0;
}

function setProgress($file, $progress) {
    file_put_contents($file, $progress);
}

// Remove invalid characters
$id = str_replace('/[^a-zA-Z0-9\-_]/', '', $_GET['id']);
$file = "progress-" . $id . ".txt";

if(isset($_GET['progress'])) {
    echo getProgress($file);
} else {
    // Do something and update progress
    for($i = 10; $i <= 100; $i += 10) {
        // Do something

        setProgress($file, $i);
        sleep(1);
    }
    unlink($file);
    echo "Result: " . rand(1, 100);
}

Edit: Added support for multiple requests and simple progress bar.


i believe that what all you need is the pecl uploadprogress package

it is not very easy to install and its not sure it works, i have find hard to make it work under certain server configurations, but i think its a good shot

EDIT: sorry i didnt see you mention download so have a look here


Below script will work for the progress-bar.

But, what I would do is, trigger an AJAX call to start the download and trigger another AJAX call to start receiving the input (using How to show file download progress in PHP Shell Scripting?).

PHP:

<?php
echo "wget '$feedURL'\n";
$execute = "wget -O ".$filePath." '$feedURL'\n";
$systemOutput = shell_exec($execute);
$systemOutput = str_replace( "\n", "\n\t", $systemOutput);
echo "\t$systemOutput\n";
?>

GetProgress:

function getProgress(){
  GDownloadUrl("getprogress.php?progress_key=<?php echo($unique_id)?>", 
               function(percent, responseCode) {
                   document.getElementById("progressinner").style.width = percent+"%";
                   if (percent < 100){
                        setTimeout("getProgress()", 100);
                   }
               });

}

Here is nice implementation with the help PHP's APC to get a nice progress-bar during UPLOAD of a file - http://www.haughin.com/2007/10/23/php-upload-progress-with-php-52-apc/


Alternative solution: You can store the progress of downloading file into $_SESSION array inside PHP. Besides that, you can write a dedicated PHP to only retrieve this percentage from session. This PHP will be called from your client's AJAX. This way the proccess won't take so much resources from server to calculate or to echo the download's percentage.

Try to avoid I/O from files if you are going to handle high rates of reading/writing onto them. Session variables are less expensive to achieve this functionality.


Provided that your PHP has some way to know the progress percentage, you should do multiple requests for progress updates:

function receiveProgress(data) {
    // update progres indicator here
    if (parseFloat(data) < 100) {
        setTimeout(checkProgress, 100);
    } else {
        pressedButton = '';
    }
}

function checkProgress() {
    $.post("script.php", {val:pressedButton}, receiveProgress);
}


var pressedButton = '';
$("#button1").click(function(){
    pressedButton = 'but1';
    checkProgress();
});

This will ask server for progress updates every 100ms

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜