doumao1047 2013-01-28 19:14
浏览 57
已采纳

PHP / Ajax轮询进度

I am attempting to implement a live polling of a php script loop with no luck thus far in my attempts. Here is what I have thus far:

On form submit:

$.ajax({
data: $(this).serialize(),
success: showResponse,
url: 'process.php',
type: 'post'
});

function showResponse(){
$.ajax({
type: "GET",
url: "progress.php",
cache: false,
success: function(data) {
var response = $.parseJSON(data);
if (response.processing === true) {
console.log("Current Item: " + response.currentItem +
"Total Items: " + response.totalItems +
 "Percent Complete: " + response.percentComplete);
setTimeout(checkProgress, 1000);
});
}

In the process.php script:

session_start();
echo json_encode(array("processing" => true));
$totalItems = 10000000;
$_SESSION['totalItems'] = $totalItems;
$_SESSION['processing'] = true;
$_SESSION['error'] = false;
for ($i=0; $i <= $totalItems; $i++) {
$_SESSION['currentItem'] = $i;
$_SESSION['percentComplete'] = round(($i / $totalItems * 100));
}

In the progress php script:

session_start();
echo json_encode(array(
"processing" => $_SESSION['processing'],
"error" => $_SESSION['error'],
"currentItem" => $_SESSION['currentItem'],
"totalItems" => $_SESSION['totalItems'],
"percentComplete" => $_SESSION['percentComplete']
)
);

Not sure where I am going wrong here but all it does is loop once it hits 100% complete. Any suggestions would be greatly appreciated!

EDIT I changed the above to using apc in the process.php:

apc_store('totalItems', $totalItems);
apc_store('processing', true);
apc_store('error', false);
apc_store('currentItem', $i);
apc_store('percentComplete', round(($i / $totalItems * 100)));

And within the progress.php:

echo json_encode(array(
"processing" => apc_fetch('processing'),
"error" => apc_fetch('error'),
"currentItem" => apc_fetch('currentItem'),
"totalItems" => apc_fetch('totalItems'),
"percentComplete" => apc_fetch('percentComplete')
    )
);

Still doesn't work properly the way I am wanting it to work, am I doing something incorrectly? It only shows false values until the script completes and shows 100% just like the session use was doing before. Any ideas?

  • 写回答

1条回答 默认 最新

  • duanhuan7750 2013-01-28 19:21
    关注

    The session information is a resource that can only be used exclusively, and you have not taken this into account.

    Specifically, under default settings session_start causes PHP to acquire an exclusive lock on a file that contains the session data. This file is not unlocked until the script exits or session_write_close is called.

    In your example, process.php acquires the lock and starts working. In the meantime, progress.php tries to session_start() and cannot (due to the lock). Enough time needs to pass for process.php to complete and exit (thus releasing the lock) before the request for progress information can be satisfied.

    A small change you can make that will have immediate effect is to call session_write_close and session_start from within your worker loop:

    for ($i=0; $i <= $totalItems; $i++) {
        session_start();
        $_SESSION['currentItem'] = $i;
        $_SESSION['percentComplete'] = round(($i / $totalItems * 100));
        session_write_close();
    }
    

    This will allow the two scripts to take turns locking the session storage file, so you will see things working as intended. However, performance will tank (this is a really impolite way to treat the session storage file).

    If you had need to do something like this in the real world, it would be necessary to utilize something other than the session data to enable this exchange of information between the PHP scripts (e.g. an in-memory cache like APC or memcached).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么