Previous Section  < Day Day Up >  Next Section

8.6 Why setcookie( ) and session_start( ) Want to Be at the Top of the Page

When a web server sends a response to a web client, most of that response is the HTML document that the browser renders into a web page on your screen: the soup of tags and text that Internet Explorer or Mozilla formats into tables or changes the color or size of. But before that HTML is a section of the response that contains headers. These don't get displayed on your screen but are commands or information from the server for the web client. The headers say things such as "this page was generated at such-and-such a time," "please don't cache this page," or (and the one that's relevant here) "please remember that the cookie named userid has the value ralph."

All of the headers in the response from the web server to the web client have to be at the beginning of the response, before the response body, which is the HTML that controls what the browser actually displays. Once some of the body is sent梕ven one line梟o more headers can be sent.

Functions such as setcookie( ) and session_start( ) add headers to the response. In order for the added headers to be sent properly, they must be added before any output starts. That's why they must be called before any print statements or any HTML appearing outside <?php ?> PHP tags.

If any output has been sent before setcookie( ) or session_start( ) is called, the PHP interpreter prints an error message that looks like this:

Warning: Cannot modify header information - headers already sent by

(output started at /www/htdocs/catalog.php:2) in /www/htdocs/catalog.php on line 4

This means that line 4 of catalog.php called a function that sends a header, but something was already printed by line 2 of catalog.php.

If you see the "headers already sent" error message, scrutinize your code for errant output. Make sure there are no print statements before you call setcookie( ) or session_start( ). Check that there is nothing before the first <?php PHP start tag in the page. Also, check that there is nothing outside the <?php ?> tags in any included or required files梕ven blank lines.

An alternative to hunting down mischievous blank lines in your files is to use output buffering. This tells the PHP interpreter to wait to send any output until it's finished processing the whole request. Then, it sends any headers that have been set, followed by all the regular output. To enable output buffering, set the output_buffering configuration directive to On in your server configuration. Web clients have to wait a few additional milliseconds to get the page content from your server, but you save megaseconds fixing your code to have all output happen after calls to setcookie( ) or session_start( ).

With output buffering turned on, you can mix print statements, cookie and session functions, HTML outside of <?php and ?> tags, and regular PHP code without getting the "headers already sent" error. The program in Example 8-19 works only when output buffering is turned on. Without it, the HTML printed before the <?php start tag triggers the sending of headers, which prevents setcookie( ) from working properly.

Example 8-19. A program that needs output buffering to work

<head>Choose Your Site Version</head>



setcookie('seen_intro', 1);


<a href="/basic.php">Basic</a>


<a href="/advanced.php">Advanced</a>



    Previous Section  < Day Day Up >  Next Section