Progress bar in ... PHP
2004-10-21 09:03:56
Background information
I have to import a massive amount of data from Excel to MySQL. Everything fine, except for two details: I have to use set_time_limit(600); to exceed maximum execution time allowed on server (no problem) and during all this process the echo's I have inside the looong loop arent showing on screen. This is worrying, because the person that will perform the import might think anything's gone wrong. So I start looking for a solution...
Getting close
Looks like php comes with some functions to manage the output buffering on screen. They're flush() and ob_flush(). I honestly don't get the difference but as said in the manual, it's best used in conjunction to make sure page contents are shown by browser. We tried in each loop step and voila! It works! Then I start thinking if it'd be possible to show a progress bar in PHP... And it is too! Cannt believe it. Of course, only under some circumstances, but it's so cool. Come and see...
Requirements
This progress bar is only intended in a case where we do not output data on screen while performing a big loop (import process, for instance, or a huge query in parts, etc). If we want to output data we just need to add flush();ob_flush(); to the end of each loop step to make the buffer flush. But instead of outputting data (i.e. a registry per line as loop passes) I think it's more elegant showing a progress bar. So, we wont output data but only information that something is happening.
Solution
We will add the following code before the loop:
echo "<div id='progress' style='position:relative;padding:0px;
width:650px;height:960px;left:25px;'>";
That starts a block (a layer) where we will be showing button-like information as a progress bar, adding the following code inside each loop step:
echo "<div style='float:left;margin:5px 0px 0px 1px;width:2px;
height:12px;background:red;color:red;'> </div>";
flush();
ob_flush();
And we will finish closing the layer once outside the loop and hiding the progress bar with this little script:
echo "</div>";
echo "<script>";
echo "document.getElementById('progress').style.display = 'none';";
echo "</script>";
You can see an example where we simulate a huge job in the data base (actually, we just pause the loop using sleep(1); that pauses each step one second). And here you have the source code of the PHP progress bar. Enjoy it ;)
This technique does not show percentages, though we could make more steps and calculate the maximum returned number of rows and add a proportional counter, etc. I'll leave it to you as homework.