I have a feeling this might be a session lock problem (ref Progress bar with PHP & Ajax ) - I've spent most of the day debugging and searching for a solution, so looking for some expert advice and tell me what is going on and how to resolve it. This is my first outing with session vars.
EDIT: I tried adding the following around each update to the session var:
session_start();
$_SESSION['percentage']=floor(($count/$total) *100);
session_write_close();
and received:
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent...
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent...
Thank you.
I have 3 files:
- firstFile.php which takes form data, makes an API call, collects the results and passes to...
- ajaxFile.php which takes the ajax data and performs further API calls and outputs the results to an html table
- progress.php which accesses the session variable "percentage" to either set it to 0 or to unset it.
Because the API calls in ajaxFile may take several seconds to process, I've implemented the progressbar UI, and is updated based on the session variable "percentage".
However, the progress bar only gets updated once ajaxFile completes.
The code is below. FYI, you might notice some odd looking logic that sets the progress bar to 98% when ajaxFile completes and then increments to 99 & 100, but that's just from my debugging efforts.
firstFile.php
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var progressbar = $( "#progressbar" ),
progressLabel = $( ".progress-label" );
progressbar.progressbar({
value: false,
change: function() {
progressLabel.text( progressbar.progressbar( "value" ) + "%" );
},
complete: function() {
progressLabel.text( "Complete!" );
}
});
$('#myForm').submit(function() {
progressbar.progressbar({
value: false,
change: function() {
if(progressbar.progressbar( "value" )==false){
progressLabel.text('Loading...');
}else{
progressLabel.text( progressbar.progressbar( "value" ) + "%" );
}
},
complete: function() {
progressLabel.text( "Complete!" );
}
});
var i = 0;
var gArr = new Array ();
var numberofloop=10;
var increment=10;
$( "#progressbar" ).progressbar( "option", "max", 100 );
$( "#progressbar" ).show();
for (var i=0;i<numberofloop;i+=increment){
var url = "API call at some domain.com";
var form=$(this).serialize();
$.ajax({
type: "GET",
url: url,
data: "",
//async: false,
dataType: "jsonp",
success: function(data) {
process data and push into array gArr}
if(gArr.length==(i/increment) ){
$.ajax({
type: "POST",
url: "ajaxFile.php",
data: { gData : gArr },
async: true,
beforeSend: function( xhr ) {
ajaxprogress();
}
}).done(function(html) {
jQuery('td#myFormResults').html(html);
$( "#progressbar" ).progressbar( "option", "value", 98 );
show();
});
}
},
error: function(data){
}
});
}
return false;
});
});
function ajaxprogress(){
$.ajax({
type: "POST",
url: "progress.php",
data: '',
//async: true,
dataType: "json",
}).done(function(html) {
var progressbar = $( "#progressbar" ),
progressLabel = $( ".progress-label" );
$( "#progressbar" ).progressbar( "option", "value", html.value );
var val = progressbar.progressbar( "value" ) || 0;
if ( val < 98 ) {
setTimeout( ajaxprogress, 10 );
}
});
}
function show(){
if($( "#progressbar" ).progressbar( "value" )!='100'){
var progressbar = $( "#progressbar" );
var val = progressbar.progressbar( "value" ) || 0;
progressbar.progressbar( "value", val + 1 );
setTimeout( show, 1000 );
}else{
var tab = jQuery('table#myFormTable');
$( "#progressbar" ).hide();
tab.show();
}
}
function sleep(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
function progress(time) {
var progressbar = $( "#progressbar" ),
progressLabel = $( ".progress-label" );
var val = progressbar.progressbar( "value" ) || 0;
progressbar.progressbar( "value", val + 1 );
if ( val < 98 ) {
setTimeout( progress, 100 );
}
}
</script>
</head>
<body>
<div id="progressbar" style="display:none;"><div class="progress-label">Loading...</div></div>
<div class="fl" name="bizParms" style="width:950px; height:50px;" >
<form action="firstFile.php" id="myForm" method="get">
<table>
<tr>
<td for various input boxes>
<td><input type="submit" name="process" id="process" value="process" /></td>
</tr>
</table>
</form>
</div>
<div>
<table>
<tr>
<td id="myFormResults">
</td>
</tr>
</table>
</div>
</div>
</body>
</html>
ajaxFile.php
if (isset($_SESSION)) {
session_start();
}
global $total;
global $count;
$count=0;
$total=1;
$_SESSION['percentage']=0;
extract all required data from $_REQUEST and put into an array "nArr"
$total=count($nArr);
foreach ($nArr as $n) {
$i++;
// for every 10 elements in the array, make an API call
if (($i %10 == 0)|| ($i == count($nArr))){
make a new API query using parameters from nArr
$apiResults = API call to some domain.com
$s = array();
$s = $apiResults;
foreach ($s as $n) {
$count++;
$_SESSION['percentage']=floor(($count/$total) *100);
$perc =floor(($count/$total) *100);
echo the data returned from the API result into a table
} // foreach
sleep(1); // space out the execution to test the progress bar
} // hit 10 results or end of array
} // foreach item in nArr
//unset($_SESSION['percentage']);
$_SESSION['percentage']=100;
progress.php
session_start();
if(isset($_SESSION['percentage'])){
echo json_encode(array('value'=>$_SESSION['percentage']));
if($_SESSION['percentage']>99){
unset($_SESSION['percentage']);
}
}else{
echo json_encode(array('value'=>0));
}