473,396 Members | 1,813 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,396 developers and data experts.

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

Markus
6,050 Expert 4TB
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
6 11453
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
is it essential to put <?php....?> inside a <html>...</html> tag
Oct 13 '10 #3
Dormilich
8,658 Expert Mod 8TB
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
1,044 Expert 1GB
@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
thanx kovik
Oct 14 '10 #6
Thanks Mr.Markus..
I read contents you have sent.
They help me to alleviate my doubts..
Feb 3 '11 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Phyzlo | last post by:
Hello, I've recently started learning PHP and have a question. I tried running below script which can be found at http://se2.php.net/manual/sv/function.setcookie.php but I keep getting this...
2
by: Dariusz | last post by:
I have a problem where when I run the PHP code offline, there are no errors produced and the code runs as expected. However when I uploaded the same script and run it, it says the headers have...
1
by: None | last post by:
Hello, I am a total newbie to PHP and programming in general. I am playing around with a PHP / MySQL shopping cart script which I found at...
6
by: Douglas F. | last post by:
My host doesn't use buffering so I placed the form validation (php) ahead of the html like this: <?php if(isset($_POST)) { <do the validation processing> if(file_exists($fn)) {...
5
by: Philip Ronan | last post by:
OK, here's my 2p worth: === Q. Why am I getting the error message 'Headers already sent'? A. PHP produces this error message when you try to set a header for a web page after you have already...
3
by: lawrence k | last post by:
I'm getting this warning: PHP Warning: session_start(): Cannot send session cache limiter - headers already sent in...
4
by: three-eight-hotel | last post by:
I'm somewhat of a newbie to PHP coding, but have developed a site using the technology, and have been pleasantly surprised by the capabilities offered. I am more comfortable in the ASP world,...
0
Atli
by: Atli | last post by:
What to discuss: What is a "MySQL resource". What causes the error. How to fix it. Common Newbie Pitfalls This article is the second installment in a series of (hopefully) many, following...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.