Proper use of headers in php

Headers seem to always give me trouble.  There seems to be the rule that they must be the first code to get executed on the page, but I always run into trouble when I need to use multiple headers or different headers based on the outcome of an if/else.  The project I'm working on specifically is an excel export of a database but the client doesn't want to have to login.  So I have to at least put a noindex/nofollow robot on the page.  When I add the doctype, <html>, <head>, <body> tags to put the robot in I get the error with the headers not being at the top.  This rule seems to be enforced at times and not at others.  There must be something I'm not seeing that triggers it.

My question is (all though maybe broad) what is the proper use of headers? or if anything how to get around this rule or what alternatives there are to headers.
Who is Participating?
Hugh McCurdyConnect With a Mentor Commented:
You could use ob_start() and ob_end_flush().

Please read the manual page for ob_start()

What I've done is issue an ob_start() right at the beginning; right after session_start() in my code.  Then after I get past the last header() call, I issue an ob_end_flush() to write out all the HTML code that is pending.  Of course, if I call header() instead, then the ob_end_flush() never happens.

I'm sure there are other approaches but this one has worked for me.


The general rule is that headers must be sent before any page output is done from any source.  PHP, lines in HTML, etc.  Check out the following page from the php reference manual.


Slick812Connect With a Mentor Commented:
greetings andrewaiello, because of the way internet data exchange takes place, a PHP page must always have finished writing the HTML page headers, before any page HTML output is added to the server output buffer. many use the ob_start() with good success.
I have just used an output string to store all of the usual ECHO statements in a PHP page, and then set headers depending on the database select results.

first was -
echo "<html><head><title>new</title></head><body>";

changed to -
$output = "<html><head><title>new</title></head><body>";

//test for DB -
if ($row['retrive']== 'someValue')
     setcookie(retrive', $row['retrive']);// cookies are header stuff
     $output .= '<b>'.$row['retrive'].'</b>';

//last thing you do is echo output
echo $output;
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

neorushConnect With a Mentor Commented:
The reason that the rule seems to be "randomly" enforced is because of PHP's effort to help you out.  As mentioned by hmccurdy, php has output buffering, and php is smart enough to actually delay the output of the page until at has a decent amount ready to send since this is more efficient.  If PHP detects a header it will move it to the start of the output buffering before it is flushed because it knows this is correct.
e.g. a page like :
<?php header("Content-Type: text/html"); ?>
...lots of html code here....
will probably not cause an error (depending on how the server is configured) But a page like:

...lots of html code here..
<?php header("Content-Type: text/html"); ?>

will almost certainly throw an error.

The reasons headers MUST be first as the HTML specification, when you load a page it actually looks like this (your browser hides headers since this is not technically the "source" of the page):

User-Agent      Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept      text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language      en-us,en;q=0.5
Accept-Encoding      gzip, deflate
Accept-Charset      ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection      keep-alive
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">
<html xmlns="">
....lots of html code....

"Host" to "Connection" are all headers, which you could change with PHP's header() function.  No, there is no real alternative to headers, its sort of like asking what the alternative to HTML would be.  There are a few, but none you'd know about or want to try and use.
Hugh McCurdyCommented:
neorush, thanks for the excellent explanation.
andrewaielloAuthor Commented:
Okay, I've read all of your reply and have been doing a lot of reading.  Just off the bat I did get what I needed to work.  It was just a little more playing around with the ordering of my code.  But, I do have a lot of leads on things to research.  I just got back and saw from slick82's post and down now.  I didn't realize php headers were associated with HTML headers in anyway until I read the definition 10 million times.    

To hmccurdy, ob_start() pretty much just ensures that your header() lines come before any other outputted code, correct?  It seems anything after the ob_start() will not execute until you issue the ob_end_flush() (except header() lines)?  That is what I gathered from the explanation.  I still don't know of all the ways you can use ob_start() with the callback functions and everything yet.  So that may open up options to use it in other ways, I'm still looking in to it.

Thank you all for replying, I have a lot of new leads on things to research.  And I now understand headers more.


I like the idea of what slick82 posted, I didn't think of that.

Thank you, for all of your replys.
Hugh McCurdyCommented:
To hmccurdy, ob_start() pretty much just ensures that your header() lines come before any other outputted code, correct?

Yes.  I put ob_start right at the top of my page.  The first line of some of my pages look like this

<?php session_start(); ob_start(); ?>
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.