Terence Eden. He has a beard and is smiling.
Theme Switcher:

PHP - simple way to send HTTP headers before a script ends

· 1 comment · 50 words · Viewed ~2,074 times


Suppose you want PHP to keep processing after it has sent back an HTTP response. Normally, this doesn't work:

 PHP<?php
   header( "Location: https://example.com/" );
   //   Long operation.
   sleep(10);
   die();

Try it yourself. You'll have to wait 10 seconds before you get back

 < HTTP/2 302 
< location: https://example.com/

There are some complex ways to fix this - they usually involve spawning sub-processes or having a cron job run something. But there's a simpler way!

Most servers do some form of output buffering. They wait for the buffer to fill (or be explicitly terminated) before they send any content. My server was set to a buffer of 4,096 bytes. So I forced some dummy output to fill it up, then told PHP to flush the buffer:

 PHP<?php
   header( "Location: https://example.com/" );
   echo str_repeat("😆", 4097);
   flush();
   sleep(10);
   die();

Some clients, like Python's Requests, wait until they've explicitly seen the end of the response before processing it.

But, for something like curl, the above is sufficient.


Share this post on…

One thought on “PHP - simple way to send HTTP headers before a script ends”

  1. @Edent I wonder if your web server/reverse proxy would be smart enough to skip the output buffering if you sent an explicit “Content-Length: 0” header.

    I see from a reply to that Requests issue that an explicit Content-Length isn't enough to get it to hang up, which is a shame. But it might be enough for some other clients.

    Reply | Reply to original comment on hachyderm.io

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

See allowed HTML elements: <a href="" title="">
<abbr title="">
<acronym title="">
<b>
<blockquote cite="">
<br>
<cite>
<code>
<del datetime="">
<em>
<i>
<img src="" alt="" title="" srcset="">
<p>
<pre>
<q cite="">
<s>
<strike>
<strong>

To respond on your own website, write a post which contains a link to this post - then enter the URl of your page here. Learn more about WebMentions.