我试图在我的尝试中实现对PHP脚本循环的实时轮询而没有运气。以下是我到目前为止的情况:
表格提交:
$.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);
});
}
在process.php脚本中:
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));
}
在进度php脚本中:
session_start();
echo json_encode(array(
"processing" => $_SESSION['processing'],
"error" => $_SESSION['error'],
"currentItem" => $_SESSION['currentItem'],
"totalItems" => $_SESSION['totalItems'],
"percentComplete" => $_SESSION['percentComplete']
)
);
不知道我在哪里出错了,但是一旦它达到100%完成就会完成循环。任何建议将不胜感激!
修改的 我将上面的内容改为在process.php中使用apc:
apc_store('totalItems', $totalItems);
apc_store('processing', true);
apc_store('error', false);
apc_store('currentItem', $i);
apc_store('percentComplete', round(($i / $totalItems * 100)));
在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')
)
);
我仍然没有按照我想要的方式正常工作,我做错了什么?它只显示错误值,直到脚本完成并显示100%,就像之前使用的会话一样。有什么想法吗?
答案 0 :(得分:5)
会话信息是一种只能专门使用的资源,您还没有考虑到这一点。
具体来说,在默认设置下session_start
会导致PHP获取包含会话数据的文件的独占锁。在脚本退出或调用session_write_close
之前,此文件未解锁。
在您的示例中,process.php
获取锁定并开始工作。在此期间,progress.php
尝试session_start()
而不能(由于锁定)。在满足进度信息请求之前,需要为process.php
完成并退出(从而释放锁定)足够的时间。
您可以立即生效的一个小改动是从您的工作循环中调用session_write_close
和session_start
:
for ($i=0; $i <= $totalItems; $i++) {
session_start();
$_SESSION['currentItem'] = $i;
$_SESSION['percentComplete'] = round(($i / $totalItems * 100));
session_write_close();
}
这将允许两个脚本轮流锁定会话存储文件,因此您将看到按预期工作的内容。但是,性能会 tank (这是处理会话存储文件的一种非常不礼貌的方式)。
如果你需要在现实世界中做这样的事情,有必要利用会话数据以外的东西来实现PHP脚本之间的信息交换(例如像APC或memcached这样的内存缓存)。