Sending custom headers

string header ( string header_to_send [, bool replace [, int http_response_code]])

bool headers_sent ( [string &file [, int &line]])

As well as status codes, there are a variety of special HTTP headers you can send that give you greater control. For example, the "Location" header instructs browsers to request a different URL, the "Content-Type" header tells browsers what kind of content they are about to receive, and the "WWW-Authenticate" header tells browsers that they need to send some authentication information to proceed.

Each of these headers is combined with the HTTP status code to form the header of a HTTP response. This is then followed by two carriage return/line feeds, \r\n\r\n, then the actual content. For example, here is what I got when I sent a request to the popular hardware discussion site,

HTTP/1.1 200 OK
Date: Thu, 31 Jul 2003 21:35:46 GMT
Server: Apache/1.3.26 (Unix) mod_perl/1.27
Cache-Control: max-age=0
Expires: Thu, 31 Jul 2003 21:35:46 GMT
Connection: close
Content-Type: text/html

There is quite a lot of information in there - even information on how the page should be cached by proxy servers and the local web browser. It is important to note that without utilising output buffering you always need to send your HTTP headers before you send any content. This is because HTTP headers are just plain text, and are indistinguishable from content except from the fact that they come first, and are separated by two carriage returns/line feeds. In practice, this means you must send your headers before you output any content at all - even blank lines.

Sending custom headers in PHP is done using the header() function, which takes the header to send as its parameter. So, to make a browser go to when it visits a certain script, this would be used:


Note that all HTTP headers are just text, and so are easy to use. Special attention should be paid when using Location header, however, as it is used to redirect clients from one page to another. When you send a Location header, PHP will continue to parse the script after the header was issued, which wastes system resources and also may let people see pages they would otherwise not be able to see. As a result, it's best to use call "exit;" immediately after header("Location: ...") to make sure that nothing happens after the redirect notice has been sent.

The headers_sent() function, when called with no parameters, simply returns true if your HTTP headers have been sent or false otherwise. Note that is not "whether some headers have been sent", but "whether the header-sending opportunity has passed". That is, if headers_sent() returns true, sending more headers will trigger an error because non-header information has already been sent. If you pass in the two parameters as references PHP will fill them with the name of the file and the line number therein where the first output was sent.

Here it is in action:

    header("Expires: Sat, 22 Dec 1979 05:30:00 GMT");
    echo "This is some text for output.<br />";
    if (!headers_sent($filename, $linenum)) {
        // if no headers have been sent, send one
        // this will not execute, as we sent the Expires header.
    } else {
        echo "Headers already sent in $filename on line $linenum.";

That will print out the following:

This is some text for output.
Headers already sent in C:\home\header.php on line 3.


Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Reading queued headers >>

Previous chapter: HTTP

Jump to:


Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.