Search code examples
phpstreamfire-and-forget

Fire-and-forget in PHP


Final update

Seems like I did make a very simple error. Since I already have a stream implementation I can just not start reading from the stream :D


I'm trying to achieve fire-and-forget like functionality in PHP.

From php.net

<?php
ignore_user_abort(true);
header("Content-Length: 4");
header("Connection: Close");
echo "abcd";
flush();

sleep(5);    
echo "Text user should not see"; // because it should have terminated
?>

This works if I open the script with a browser. (shows "abcd"). But if I open it with file_get_contents or some stream library it will wait for ~5 seconds and show the second text as well.

I'm using PHP 5.2.11 / Apache 2.0


Update

I seems there is some confusion about what I'm trying to accomplish.

I don't want to hide output using output buffers (that's stupid). I want to have the client terminate before the server starts a possibly lengthy process (sleep(5)) and I don't want the client to wait for it (this is what fire-and-forget means, sort off). The use of output buffers is merely a side effect. I've amended the sample code without the use of output buffers.

What I don't understand is: why does this script behave differently when accessing it from the browser vs. fetching it in PHP with file_get_contents("http://dev/test.php") or some stream library? What I've seen in testing is that for instance stream_get_contents will actually block for 5 seconds before it returns any output at all, the is quite the opposite of what I want.

Update2

Some more results:

  • The browser somehow responds to the flush(). I can't figure out how to replicate this behavior with streams in PHP, my streams keep blocking.
  • I've tried fread and found that it behaves similar to stream_get_contents.
  • Specifying a maxlength has no effect, it will still block for ~5 seconds.
  • Changing the blocking mode has no effect (other than generating a bunch more calls to stream_get_contents()). It will wait ~5 seconds before returning anything.
  • stream_set_read_buffer has no effect (tested on a PHP 5.3.5 sever)

Solution

  • Seems like I did make a very simple error. Since I already have a stream implementation I can just not start reading from the stream :D