Solved

Proper use of headers in php

Posted on 2011-09-27
7
206 Views
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.
0
Comment
Question by:andrewaiello
7 Comments
 
LVL 13

Accepted Solution

by:
Hugh McCurdy earned 167 total points
ID: 36710834
You could use ob_start() and ob_end_flush().

Please read the manual page for ob_start()

http://php.net/manual/en/function.ob-start.php


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.

0
 
LVL 13

Expert Comment

by:AielloJ
ID: 36711192
andrewaiello:

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.  

http://php.net/manual/en/function.header.php

Regards,

AielloJ
0
 
LVL 33

Assisted Solution

by:Slick812
Slick812 earned 167 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
     else
     $output .= '<b>'.$row['retrive'].'</b>';

//last thing you do is echo output
echo $output;
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 6

Assisted Solution

by:neorush
neorush earned 166 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 :
<html>
<?php header("Content-Type: text/html"); ?>
<head>
...lots of html code here....
</body>
</html>
will probably not cause an error (depending on how the server is configured) But a page like:

<html>
<head>
...lots of html code here..
</body>
</html>
<?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">
<head>
....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.
0
 
LVL 13

Expert Comment

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

Author Closing Comment

by:andrewaiello
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.

Dan

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

Thank you, for all of your replys.
0
 
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(); ?>
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
Things That Drive Us Nuts Have you noticed the use of the reCaptcha feature at EE and other web sites?  It wants you to read and retype something that looks like this.Insanity!  It's not EE's fault - that's just the way reCaptcha works.  But it is …
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

757 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now