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:

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

function showResponse(){
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:

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:

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['currentItem'] = $i;
        $_SESSION['percentComplete'] = round(($i / $totalItems * 100));

    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 加一个K2暂停音乐的功能
  • ¥15 完成虚拟机环境配置,还有安装kettle
  • ¥15 2024年全国大学生数据分析大赛A题:直播带货与电商产品的大数据分析 问题5. 请设计一份优惠券的投放策略,需要考虑优惠券的数量、优惠券的金额、投放时间段和投放商品种类等因素。求具体的python代码
  • ¥15 有人会搭建生鲜配送自营+平台的管理系统吗
  • ¥15 用matlab写代码
  • ¥30 motoradmin系统的多对多配置
  • ¥15 求组态王串口自定义通信配置方法或代码?
  • ¥15 实验 :UML2.0 结构建模
  • ¥20 用vivado写数字逻辑实验报告撰写,FPGA实验
  • ¥15 为什么shp文件会有这种小方块?