Proper use of headers in php

Posted on 2011-09-27
Medium Priority
Last Modified: 2012-05-12
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.
Question by:andrewaiello
LVL 13

Accepted Solution

Hugh McCurdy earned 668 total points
ID: 36710834
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.

LVL 13

Expert Comment

ID: 36711192

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.  



LVL 34

Assisted Solution

Slick812 earned 668 total points
ID: 36712462
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;

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Assisted Solution

neorush earned 664 total points
ID: 36712497
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):

Host      www.experts-exchange.com
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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
....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.
LVL 13

Expert Comment

by:Hugh McCurdy
ID: 36712600
neorush, thanks for the excellent explanation.

Author Closing Comment

ID: 36712934
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 php.net 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 php.net 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.
LVL 13

Expert Comment

by:Hugh McCurdy
ID: 36712980
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(); ?>

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to count occurrences of each item in an array.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses
Course of the Month16 days, 2 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question