4

我尝试为一个简单的 php 循环制作某种进度指示器。

这里有很多关于进度和 php 循环的 ajax / php 问题,但是在阅读了很多之后,我仍然无法实现(也不完全理解)逻辑..

他们中的大多数要么在谈论-upload-进度条,要么过于本地化到特定情况。(要么 - 要么我不知道如何选择正确的关键字进行搜索。)

我的最终目标是制作一个进度条,但首先,我尝试了一个小回声循环。

我尝试了以下方法:

HTML 表单:

<p class="submit">
    <input type="submit" class="button-primary" id="o99_sudi_do_now" value="<?php _e('DO IT NOW !', 'o99_sudi_domain'); ?>" />
    <img src="<?php echo admin_url('/images/wpspin_light.gif'); ?>" class="waiting" id="o99_sudi_loading" style="display:none;"/>
</p>

            <div id="o99_sudi_results"></div>

jQuery

jQuery(document).ready(function($){
  jQuery('#o99_sudi_do_now_form').click(function(e){
    e.preventDefault();
    jQuery.post(ajaxurl,{action:'o99_random_loop'}, function(data){
      jQuery('#o99_sudi_results').empty().append( data );
    });
  });
});

PHP

function o99_random_loop_cb(){
 for ($i = 0; $i < 10; $i++) {
        //ob_end_clean(); // [TESING]
        echo '-- step' .$i . ' of 10</br>';
        //flush();// [TESING]
        //usleep(100000000000*0.1); // total time 10 sec.// [TESING]
        //ob_flush();// [TESING]
        usleep(20000);
    }
  die();

并且因为它都在 wordpress 管理区域中 -

add_action( 'wp_ajax_o99_random_loop', 'o99_random_loop_cb' ); 

结果(或输出)是

-- Step 0 of 10
-- Step 1 of 10
-- Step 2 of 10
-- Step 3 of 10
-- Step 4 of 10
-- Step 5 of 10
-- Step 6 of 10
-- Step 7 of 10
-- Step 8 of 10
-- Step 9 of 10

这有点好,但问题是输出到达并且只有在执行完成时才更新 div - 我希望它能够即时更新,逐步......(我真正的计划循环很长,迭代大约需要 2-3 秒。)

就像你可以看到的代码一样,我已经尝试过flush();ob_flush();以及我看到的任何其他建议,但我怀疑这里的逻辑是错误的(因为它是 wordpress??或者在错误的地方刷新?)实际上,无论如何很多我flush(); - 结果仅在函数结束时到达..

我的目标是制作一个进度条 - 但现在即使是简单的回声进度的帮助也会很棒..

4

1 回答 1

5

您无法通过对 PHP 的单个 POST 来实现您想要的。即使刷新 PHP 输出,jQuery 端也不会处理结果处理程序,直到整个 PHP 进程完成。很久以前,只有一些浏览器(Netscape 等)会在文档完成之前开始显示内容,但是,使用 AJAX,在 PHP 脚本完成之前,您不会看到任何来自 PHP 的结果内容。完成的。

因此,您一次获得所有输出的原因。

有几种可能的方法可以完成您想做的事情。一种方法是将您的 PHP 循环分成多个阶段,以便每次只执行循环的一部分。然后,您可以执行几次迭代(甚至一次迭代)并将结果返回给浏览器。然后浏览器将显示结果并再次调用 PHP 以进行下一次迭代(或一组迭代)。虽然这会给您提供进度指示器,但它会大大减慢您的整体操作速度,因此不推荐。

编辑以删除由于并发问题而无法使用的 SESSION 的使用:

另一种选择是让 PHP 将循环的进度保存到数据库中,并让浏览器端定期轮询另一个 PHP 脚本,该脚本检查数据库以确定进度。在快速循环中,这不会有太大帮助,但在更长的运行循环中,这可能是可行的。因此,随着您的 $.post 调用,您将开始一系列定时的 $.get 调用以检查进度。

编辑:这里有一些片段来说明:

// variable to control polling logic
var pollInterval;
// Your current post logic here with the addition of a variable to stop execution of the polling process
jQuery.post(ajaxurl,{action:'o99_random_loop'}, function(data){
    // post is complete so stop execution
    window.clearInterval(pollInterval);
});
// Now start a get process to get the progress every 5 seconds
pollInterval = window.setInterval(function () {
    // I'm assuming pollingurl is the URL to your PHP script that checks the progress
    jQuery.get(pollingurl, function(data){
        jQuery('#o99_sudi_results').empty().append( data );
    });
}, 5000);

我现在假设在 PHP 方面,您可以轻松地将进度保存到数据库表并从表中检索所述进度。

于 2012-11-14T11:18:09.013 回答