I'm using JQuery and AJAX to call a slow function in a PHP file, but I don't get a response until the PHP function is complete. I can't figure out why, despite 2 days of searching. I've shrunk it down to two test files, that exhibit exactly the same behaviour. My php function is thus, in a file called "ajaxfuncs.php":
<?php
Class AjaxFuncs{
public function __construct() {
$this->testbuffer ();
}
function testbuffer(){
echo 'Starting Test Buffer Output. There should be a 2 second delay after this text displays.' . PHP_EOL;
echo " <br><br>";
echo '<div id="testdata" class="testdata">0</div>';
// The above should be returned immediately
flush();
// Delay before returning anything else
sleep(2);
for ($a = 0; $a < 3; $a++) {
echo '<script type="text/javascript">document.getElementById("testdata").innerHTML="' . (int)($a + 1) . '"</script>';
flush();
// Delay for 1 second before updating the value
sleep(1);
}
}
}
$AjaxFuncs = new AjaxFuncs();
?>
The above works if I open the "ajaxfuncs.php" file in the browser. It does exactly as I'd expect, and the output updates every second until complete. So I know I've buffering sorted on the server.
But when I call it using the following $.ajax it's not right. I've put everything except the php for the ajax function into another php file called "testindex.php" for convenience. This is it:
<?php
header( 'Content-type: text/html; charset=utf-8' );
header("Cache-Control: no-store, must-revalidate");
header ("Pragma: no-cache");
header("Expires: Mon, 24 Sep 2012 04:00:00 GMT");
?>
<body>
<a>Test Page. Wait for it...</a>
<div id="maincontent">
</div>
</body>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<script>
$(document).ready(function(){
console.log ('Document Ready');
function callajax(){
var ajaxfilepath = "ajaxfuncs.php";
return $.ajax({
url: ajaxfilepath,
data: {action: 'testbuffer'},
type: 'get',
cache: false,
dataType: "text",
beforeSend: console.log('Starting Ajax Operation')
})
.done(function(result){
processajaxcalloutput(result);
})
.always(function(){
console.log(' Ajax Internal Complete Detected');
})
.fail(function( jqXHR, textStatus ) {
console.log( "Ajax Request failed: " + textStatus );
});
}
function processajaxcalloutput(result){
var message = 'Processing Ajax Response' ;
console.log(message);
$("#maincontent").append(result);
}
callajax();
});
Everything works without error. Console is clear - no errors (I'm testing with Chrome & Firefox). But I can't seem to get a response until the entire PHP function is done. I've tried everything I can find, in particular hundreds of different things to force caching off, but to no avail. Any help is much appreciated. Thanks.
Update: So based on the feedback so far, it's clear the call is asynchronous and the code is fine, but asynchronous does not mean I'll get a continuous stream of output data from the php function as it executes. Instead the entire response will be returned at the end of the execution. Rather than divert this question into one about streaming, I'll leave it at this until I resolve the streaming issue.