I try to make some kind of progress indicator for a simple php loop.
There are a lot of ajax / php questions here regarding progress and php loops, but after reading a lot of them, I still can not implement (nor understand exactly ) the logic..
Most of them are either talking about -upload- progress bar or are too localized to a specific case .( either that – or I do not know how to choose the right keywords to search.)
My final goal is to make a progress bar, but to start, I tried a little echo loop.
I tried the following :
HTML form :
<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();
and since it is all in a wordpress admin area –
add_action( 'wp_ajax_o99_random_loop', 'o99_random_loop_cb' );
the result (or output) is :
-- 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
which is kind of ok , but the problem is that the output arrives and the div is updated only when the execution is finished – and I want it to be updated on-the-fly ,step by step… (my real planned loop is quite long and will take about 2-3 seconds for iteration. )
Like you can see with the code, i have tried flush(); , ob_flush(); and any other suggestion that I have seen , but I suspect that the LOGIC is wrong here (because it is wordpress?? or flushing in wrong place ?) and actually , no matter how much I flush(); – the result arrive only when the function is ENDING ..
My goal is to make a progress bar – but for now even help with a simple echoing progress will be great ..
You can’t achieve what you want with a single POST to PHP. Even if you flush your PHP output, the jQuery side won’t process the result handler until the entire PHP process is complete. Long ago you could get something like this behavior with only some browsers (Netscape, etc) that would start displaying content before the document was complete, however, with AJAX you won’t see any of the resulting content from PHP until the PHP script is finished.
Hence the reason you are getting all your output at once.
There are a few possible ways to accomplish what you want to do. One method is to break your PHP loop into stages so that only a portion of the loop is executed each time. You could then execute a few iterations (or even one iteration) and return that result to the browser. The browser would then display the result and call to PHP again for the next iteration (or set of iterations). While this would give you your progress indicator it would dramatically slow down your overall operation and is not recommended.
EDITED to remove use of SESSION which won’t work due to concurrency issues:
Another option is to have PHP save the progress of your loop to a database and have the browser side regularly poll another PHP script that checks the database to determine the progress. On a quick loop this won’t be all that helpful, but on a longer running loop this could be workable. So along with your $.post call you’ll start a series of timed $.get calls to check the progress.
EDIT:
Here are a few snippets to illustrate:
I’ll assume for now that on the PHP side you are comfortable saving your progress to a database table and retrieving said progress from the table.