I am trying to add on a script of mine that is checking some factors for multiple websites a COUNTDOWN that will let the user know, live, how many hours/minutes/seconds will remain until script finishes the task. I need to do this to a php script of mine. But really don't know where to get started. I only know that is possible to COUNT the time of a script HAD BEEN executed with microtime() function. I tried searching lots of scripts here, but I barely found smth related to some dynamic progress bars (but not very well explained) and nothing to a dinamic countdown timer that can countdown execution time of script.
Would be much appreciated any help related this issue (links, functions, scripts...)
3 Answers
Without knowing what your script does, there is no way to know ahead of time how long it will take to run. Even if we did know what it does, to know the precise time it will take to run really is not possible. If this is all within the same session you could put "% complete markers" at certain main points in your script. I do this in a few places. It makes a nice progress bar and I also show the total elapsed run time as well. If something like this is what you want then read on...
(this is using a jQuery UI progress bar)

If your script is a loop and each iteration is basically doing the same thing then the growth of the progress bar will be pretty fluid. If this isn't the case, and your script does many things very fast, then a few things very slow, then you bar will be like pretty much all Windows progress bars :) It could get to a certain point very quickly then hang there for a while.
Not at my PC so I'm sure there are typos below but you should be able to get the point. Hope this helps...
Something like this would be in your long running script...
$_SESSION["time_start"] = microtime(true);
$_SESSION["percentComplete"] = 0;
... some of your php script ...
$_SESSION["percentComplete"] = 10;
... some of your php script ...
$_SESSION["percentComplete"] = 20;
... some of your php script ...
$_SESSION["percentComplete"] = 30;
... etc ...
$_SESSION["percentComplete"] = 100;
die();
?> //end of your php script
but if your long running script is a loop it would be more like this...
$loopCnt = 0;
//your php loop
{
$loopCnt = $loopCnt+1;
//...the meat of your script...
$_SESSION["percentComplete"] = round(($loopCnt/$totalRecordCount)*100);
}
$_SESSION["percentComplete"] = 100;
die();
?> //end of your php script
Then on the page the user interacts with an ajax ping could be setup to check the value of $_SESSION["percentComplete"] every couple seconds or so and make the progress bar grow based off the result. Something like...
function checkScriptProgress()
{
$.ajax({
url: "checkScriptProgress.php",
type: 'get',
cache: false,
success: function( data, textStatus, jqXHR) {
//(1) MOVE THE PROGRESS BAR
//if you are using a jQuery UI progress bar then you could do something like...
//jQuery("#yourProgressBar").progressbar( "option", "value", data.progress );
//if you are using HTML5 progress bars it would look like...
//var pBar = document.getElementById("yourProgressBar");
//pBar.value = data.progress;
//(2) UPDATE ELAPSED TIME
//if you want to display the total run time back to the user then use: data.totalRunTime
//(3) If report is not finished then ping to check status again
if (data.progress < 100) setTimeout("checkScriptProgress();", 1000); //check progress every 1 second so the progress bar movement is fluid
})
});
}
Then the checkScriptProgress.php file would look something like...
<?php
header('Content-Type: application/json');
$time_end = microtime(true);
$time = $time_end - $_SESSION["time_start"];
echo '{"progress":'.$_SESSION["percentComplete"].',"totalRunTime":'.$time.'}';
die();
?>
2 Comments
checkScriptProgress.php and my loop (loop being located on a separated file called multipr.php). The script is a multi pagerank checker and looks like this: checkprg.com/multi-pagerank-checker.html (currently I did not implemented your soludtion on the live site, is only on localhost).Before any progress has been made, an initial estimate requires an estimate of how long each action will take to complete, and the number of actions to perform. (This formula assumes that processing is not done in parallel)
final_timestamp = start_timestamp + (number_of_actions * average_duration_per_action)
Record progress, including number of actions completed and total time spent so far. This allows you to update the estimate.
updated_final_timestamp = start_timestamp + (current_timestamp - start_timestamp) / (num_action_completed / num_actions_total)
Comments
You will never be able to determine the duration of any execution task before starting the task. Thats when artificial intelligence comes to be a part of your algorithm. You will need to train your algorithm with a large set of data that will make it possible to Predict the duration of the task.
For example you can create an INSERT statement of a major part of your application and then start counting the time using microtime(). When the insert statement is done with any other pre processing, you will save this data as a training data.
In your application now .. When someones tries to use the same Process. You will say it will take about 33 seconds for example. and you use your javascript code to control the dynamic progress bar to be in 100% state after 33 seconds!
Code Example:
<?php
//** this is done in development phase **//
function MyFunction($arg1, $arg2){
// calculate the current time.
$startTime =microtime(true);
// My Process in here ......
$final_time = microtime(true) - $startTime;
// Save final time for future usage.
// Repeate the step 100 times with random data
}
// Now you can pre calculate the average of this task
// based on the previous training data.
function MyFunction($arg1, $arg2){
// Get avarege executing time for this..
// Tell the user that this function will take ? amount of time.
}
?>
This method is more reliable and efficient than counting the time while doing the task.
- You will never need to calculate the time in the middle of the task because you already did that.
- You will never need an ajax that will hit your server every second
- Your Progress bar is moving smoothly because you know the time it takes.
However, if you just need a dynamic progress bar that changes with every line of code you will need to manage your javascript inside your PHP code.
Finally, the last method will cause a problem if one line is taking more amount of time than other lines. Your progress bar may reach %90 in 3 seconds. and stop for 10 seconds in that state until it moves to 100%, which seems unreal.
- You will need to calculate the time before you start
- You will need to calculate the time after you finish
- You will need to calculate the difference between the two timestamps.
- And you will increase you progress bar Un dynamically.