My script is called by server. From server I\'ll receive ID_OF_MESSAGE
and TEXT_OF_MESSAGE
.
In my script I\'ll handle incoming text and ge
I asked this question to Rasmus Lerdorf in April 2012, citing these articles:
I suggested the development of a new PHP built-in function to notify the platform that no further output (on stdout?) will be generated (such a function might take care of closing the connection). Rasmus Lerdorf responded:
See Gearman. You really really don't want your frontend Web servers doing backend processing like this.
I can see his point, and support his opinion for some applications/ loading scenarios! However, under some other scenarios, the solutions from vcampitelli et al, are good ones.
I use the php function register_shutdown_function for this.
void register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] )
http://php.net/manual/en/function.register-shutdown-function.php
Edit: The above is not working. It seems I was misled by some old documentation. The behaviour of register_shutdown_function has changed since PHP 4.1 link link
in case of php file_get_contents use, connection close is not enough. php still wait for eof witch send by server.
my solution is to read 'Content-Length:'
here is sample :
response.php:
<?php
ignore_user_abort(true);
set_time_limit(500);
ob_start();
echo 'ok'."\n";
header('Connection: close');
header('Content-Length: '.ob_get_length());
ob_end_flush();
ob_flush();
flush();
sleep(30);
Note the "\n" in response to close line, if not the fget read while wait eof.
read.php :
<?php
$vars = array(
'hello' => 'world'
);
$content = http_build_query($vars);
fwrite($fp, "POST /response.php HTTP/1.1\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: " . strlen($content) . "\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $content);
$iSize = null;
$bHeaderEnd = false;
$sResponse = '';
do {
$sTmp = fgets($fp, 1024);
$iPos = strpos($sTmp, 'Content-Length: ');
if ($iPos !== false) {
$iSize = (int) substr($sTmp, strlen('Content-Length: '));
}
if ($bHeaderEnd) {
$sResponse.= $sTmp;
}
if (strlen(trim($sTmp)) == 0) {
$bHeaderEnd = true;
}
} while (!feof($fp) && (is_null($iSize) || !is_null($iSize) && strlen($sResponse) < $iSize));
$result = trim($sResponse);
As you can see this script dosent wait about eof if content length is reach.
hope it will help
I can't install pthread and neither the previous solutions work for me. I found only the following solution to work (ref: https://stackoverflow.com/a/14469376/1315873):
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(); // optional
ob_start();
echo ('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
session_write_close(); // Added a line suggested in the comment
// Do processing here
sleep(30);
echo('Text user will never see');
?>
Modified the answer by @vcampitelli a bit. Don't think you need the close
header. I was seeing duplicate close headers in Chrome.
<?php
ignore_user_abort(true);
ob_start();
echo '{}';
header($_SERVER["SERVER_PROTOCOL"] . " 202 Accepted");
header("Status: 202 Accepted");
header("Content-Type: application/json");
header('Content-Length: '.ob_get_length());
ob_end_flush();
ob_flush();
flush();
sleep(10);
Yes. You can do this:
ignore_user_abort(true);
set_time_limit(0);
ob_start();
// do initial processing here
echo $response; // send the response
header('Connection: close');
header('Content-Length: '.ob_get_length());
ob_end_flush();
ob_flush();
flush();
// now the request is sent to the browser, but the script is still running
// so, you can continue...