2

I've been trying to complete a script that sends the proper notification to a users browser to close the connection, but allows the server to keep processing a request. My code is based on what I've seen on:

http://www.php.net/manual/en/features.connection-handling.php#71172

and

close a connection early

ob_start();
echo ('Text the user will see');
$size = ob_get_length();
ignore_user_abort(); // optional
header('Content-Encoding: none');
header("Content-Length: $size");
header("Connection: close");
// flush all output
ob_end_flush();
ob_flush();
flush();

sleep(5);
//just a test to see if the script continues to run 
file_put_contents("trash/".date('dmY-H_i_s_1').".txt", "Some text.");
file_put_contents("trash/".date('dmY-H_i_s_2').".txt", "Some text.");
file_put_contents("trash/".date('dmY-H_i_s_3').".txt", "Some text.");

When I go to run the script, sometimes it will create the first file but not write the text to it. Sometimes it doesn't create any files. If I run the script with the return early code commented out, all three files are created just fine. Zlib compression is turned off. Any ideas?

Community
  • 1
  • 1
Vince
  • 316
  • 1
  • 5
  • 11

3 Answers3

0

You can set your extra processing to take place with register_shutdown_function.

Basically, you register something to take place after you script finishes and sends all output to the user. That way the script can keep running for a while after that doing whatever cleanup or what not is needed.

Update: My bad, that no long applies after PHP 4.1

The links you gave and the other stuff I found seems to state you are doing it right. Are you sure there isn't an error or script timeout going on? What does the PHP error log state?

Xeoncross
  • 55,620
  • 80
  • 262
  • 364
  • No errors in the error log. Its like it try's to execute the next command after the final flush and then goes away after that. – Vince Oct 04 '11 at 16:34
0

ignore_user_abort() must have a non-null parameter for it to actually ignore user abort. Otherwise it just returns the current ignore setting without changing anything. so you'd need

ignore_user_abort(true);
Marc B
  • 356,200
  • 43
  • 426
  • 500
0

The right way to do this is to use php in fastcgi mode and then you can use the function fastcgi_finish_request(); it will do exactly what you need - it will close the connection to the browser but the rest of the script will continue to run to the end.

http://php-fpm.org/wiki/Features

It's much better than relying on output buffering.

Dmitri Snytkine
  • 1,096
  • 1
  • 8
  • 14
  • I would love to give it a try, however our production environment is not currently setup to use fastcgi and it is not an immediate option to switch it over. – Vince Oct 04 '11 at 22:07