By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,972 Members | 1,454 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

PHP - Common Newbie Pitfalls, 1: Headers Already Sent.

Markus
Expert 5K+
P: 6,050
Things to discuss:
  • Headers
    • What are they?
    • What does PHP have to do with headers?
    • Why can they only be sent before any output?
  • Common causes
    • Calling a function that sends header information to the browser after one has sent output via print(), echo(), etc.
    • Calling a function that sends header information to the browser within an HTML file
  • Uncommon / Hard-to-locate (the most annoying) causes
    • Whitespace before opening the PHP parser (<?php)
    • BOM
  • Solutions
    • Moving header-sending functions to before any output
    • Output buffering

PHP - Common Newbie Pitfails

This article is the first installment in a series of (hopefully) many.

Written by the PHP experts at bytes.com, these articles hope to cover those common bear traps often encountered — and subsequently asked on the bytes.com forums — by PHP newcomers in a clear and concise manner.

1. Headers Already Sent
Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\site\php\index.php:1) in C:\xampp\htdocs\site\php\index.php on line 14
- The common error message.
Headers

What are they?

When you write a letter to a friend, before giving that letter to the post office, you provide a set of details on the front of the envelope: name, address, etc. The post office is then able to use this address to give the letter to the correct location. Were you not to give this information, the post office would be quite unsure of how to handle the letter (and it would most likely end up in the bin, but that's irrelevant here).

Headers, in this sense, are the address of whomever you are intending to write a letter: a set of information / instructions for the post office (web browser) with which it can act accordingly.

So, to move away from the analogy: headers are a set of information / instructions given to the web-browser so that it can act upon them.

A common header that you are most likely aware of is the 'mime-type' header which looks like: Content-type: text/html. This header instructs the browser that whatever follows (after the headers) is to be rendered as HTML text. Were you to send the header Content-type: text/xml, then the browser would know to render the text as XML (in Firefox, the XML will be displayed in a neat format, for example).

What does PHP have to do with them?

PHP, by the very virtue of its name — PHP: Hypertext Preprocessor — has a lot to do with headers. If you have ever worked with the C programming language you will surely have heard of the C Preprocessor. This tool parses your .c file and makes any changes to it according to your rules. If you #define IMG_X 100, the preprocessor will change all occurrences of IMG_X with 100. This is effectively what PHP does, too. What does this have to do with headers? Well, it's what happens after the preprocessing that includes headers (or can do). PHP pushes whatever data resides in its buffer to the web-browser. Therefore, PHP has the ability to send headers to the browser.

Why can headers only be sent before output / why can they not be modified after output?

The answer to this is quite simple: once the browser has received the headers, it will not recognise any subsequent headers, thus making any attempts to do so pointless.

You may also ask: well, that doesn't sound so dangerous - why does PHP make a fuss about it? The answer again is simple: some functions in the PHP core rely on the need to send header information to the browser. We'll have a look at this in more detail when we come to those functions.

Causes

For every problem that arises there are always at least a couple of causes, and there'll always be those that make themselves that bit harder to find.

The common(er) causes.
  • session_start()

    The single most common cause of the title error, through my experience, is calling the session_start() function after sending output to the browser. The offending code often looks like this:
    Expand|Select|Wrap|Line Numbers
    1. <html>
    2.     <head></head>
    3.     <body>
    4.     <h1>Starting session...</h1>
    5.     <?php session_start(); ?>
    6.     </body>
    7. </html>
    8.  
    The session_start() function is one of those aforementioned functions that relies on sending header information to the browser.

    To implement the session, PHP needs to create a cookie on the client's browser that will store the session ID. However, as we discovered before, if output has already been sent to the browser, PHP cannot then send the cookie header to the browser, thus the call to session_start() fails.

    However, session_start() is not the only function to have this behaviour. Other functions include (incomplete list):
    * Another common error is calling the header() function to redirect the user after output has been sent. The following is another frequent offender:
    Expand|Select|Wrap|Line Numbers
    1. <html>
    2.     <head></head>
    3.     <body>
    4.     <h1>Redirecting in 5 seconds...</h1>
    5.     <?php
    6.         header("refresh: 5; url=/page.html");
    7.         // Or
    8.         header("location: /page.html");
    9.     ?>
    10.     </body>
    11. </html>
    12.  
  • Another common cause, which is really just a reiteration of the previously mentioned one, is calling a function like echo()* or print()* and then calling a function that is header-dependant. Just as with the session_start() and header() examples, this will cause an error/warning for the exact same reasons. Once you call echo() or print() the headers will be sent (the first time you call the function, that is), and, therefore, you cannot send them again with a call to session_start() or header(), etc.
    Expand|Select|Wrap|Line Numbers
    1. <?php
    2.     print 'This call to print() implicitly flushes the headers to the browser.';
    3.     session_start(); // :(
    4. ?>
    5.  
    * Technically speaking, these are language constructs and not functions - but that's neither here nor there.

The Uncommon causes.
Debugging is, in general, a lengthy and tiresome task. The debugging skill of the programmer is probably the biggest factor in the ability to debug a problem [...]

- Wikipedia: debugging.
  • BOM (Byte-order Mark)

    The Byte-order Mark is a sequence of characters that denotes how bytes are ordered. To explain it in detail would be to go out of the scope of this article (and also to digress).

    All you need to know is that various — typically Windows-based — programs add this sequence of characters to the very beginning of a file. When PHP opens this file, it sees the characters and thinks to itself OK, we have some output to send to the browser! and then the headers are implicitly flushed and then the content is sent.

    Therefore, if you have any calls in that file to a function such as header(), you will encounter that familiar error.
  • Whitespace before the opening PHP tag

    This is one more common than the BOM problem and easier to spot but still just as frustrating, although the errors arise for exactly the same reason: anything before the opening PHP tag (<?php) will be thought of as output and sent to the browser, thereby flushing the headers also.

Solutions

The solutions are in fact very simple and are generally the same.

As we saw from all of the causes, the error arises when content is knowingly or unknowingly sent to the browser. From this we can deduce that the solution would be to not send any output before sending the headers. Consider the following example:
  • session_start()

    We saw before that starting the session after outputting some HTML would cause problems:

    Expand|Select|Wrap|Line Numbers
    1. <html>
    2.     <head></head>
    3.     <body>
    4.     <h1>Starting session...</h1>
    5.     <?php session_start(); ?>
    6.     </body>
    7. </html>
    8.  
    If we were to move the call to session_start() to the beginning of the file we would not see any errors!

    Expand|Select|Wrap|Line Numbers
    1. <?php session_start(); ?>
    2. <html>
    3.     <head></head>
    4.     <body>
    5.     <h1>Starting session...</h1>
    6.     </body>
    7. </html>
    8.  
  • Whitespace before the opening PHP tag

    A very easy fix for this one - remove the whitespace! Sometimes it's not so obvious that it's there, so be sure to look carefully!

    Expand|Select|Wrap|Line Numbers
    1.  <?php // notice there _is_ a space before the opening PHP tag.
    2. session_start();
    3. ?>
    4.  
  • BOM

    With this cause the solution isn't as simple as simply removing any whitespace, or moving function calls to the beginning of a file because the text editor that places these characters into the file also makes them invisible! Also, the solution isn't the same across all text editors. For this reason, I will provide you with the search keywords for google: remove BOM <insert text editor name here>

Output Buffering

Sometimes you may find that on a large code-base, restructuring the code to alleviate these errors may be too time-consuming. Therefore, you'll need a quick-fix. Output Buffering may be just what you need.

Output buffering does what it says on the tin: buffers (stores) your output until you're ready to flush (send) it. Using this technique, you can buffer a block of code like so:

Expand|Select|Wrap|Line Numbers
  1. <?php
  2.  
  3. /** Kick start output buffering */
  4. ob_start();
  5.  
  6. /** Send some output */
  7. print 'Sending output!';
  8.  
  9. /** Call a header-dependant function */
  10. session_start();
  11.  
  12. /** flush the buffer contents */
  13. ob_end_flush();
  14.  
Now, you might have thought to yourself well, won't PHP buffer the headers too? And the answer is: no. The output buffering functions do not affect any functions that need to send headers - that's the beauty of it!

Conclusion

So, there you go. I understand this article got a little more comprehensive than I intended, but never mind.

May the source be with you,

Mark Skilbeck.

P.S. Please mention any spelling/grammar errors and any information that is incorrect.
Oct 30 '09 #1
Share this Article
Share on Google+
6 Comments


P: 50
I would like to add that you can turn output buffering on in the php.ini file or .htaccess file ( if your server supports them of course ). Common value is 4096 the value is the number of bytes PHP will store in its output buffer you can set it to "on" rather then a number for no size limit.

For development purposes it is still good to practice and understand the way shown above so you know how to correct the problem if the server disallows .htaccess files and personal php.ini files.
Mar 16 '10 #2

P: 9
is it essential to put <?php....?> inside a <html>...</html> tag
Oct 13 '10 #3

Dormilich
Expert Mod 5K+
P: 8,639
don’t understand the question. it is essential to put PHP code in <?php … ?>. any HTML code is uninteresting for PHP.
Oct 13 '10 #4

kovik
Expert 100+
P: 1,044
@bikashliju: No, it is not. In fact, more experienced PHP developers like us put most of our code far before any HTML is ever output, including the <html> tag.
Oct 13 '10 #5

P: 9
thanx kovik
Oct 14 '10 #6

Prakash Gnana
P: 25
Thanks Mr.Markus..
I read contents you have sent.
They help me to alleviate my doubts..
Feb 3 '11 #7