PHP Home Page

Manual Table of Contents
Up to HTTP
Quick Reference
English version of this pageGerman version of this pageJapanese version of this page
Italian version of this pageFrench version of this pageHungarian version of this page
Spanish version of this pageDutch version of this pageBrazilian Portuguese version of this page
Korean version of this pageCzech version of this page
HTTP
* header
* headers_sent
* setcookie

  Thanks to:
 Chek.com
 easyDNS
 VA Linux Systems

  Related sites:
Apache
MySQL
PostgreSQL
Zend Tech.

  Community:
LinuxFund.org
OSDN
Manual: header
View the source code for this pageSearch the site



Previous page
 HTTP
 Updated
Sun, 11 Feb 2001
headers_sent 
Next page


header

(PHP 3, PHP 4 )

header -- Envoie un entête HTTP.

Description

int header (string string)

header() permet de spécifier un entête HTTP lors de l'envoi des fichiers HTML. Reportez vous à HTTP 1.1 Specification pour plus d'informations sur les entêtes HTTP. NB : la fonction header() doit être appelée avant la première balise HTML, et avant n'importe quel envoi de commande PHP. C'est une erreur très courante que de lire du code avec la fonction include() ou avec auto_prepend et d'avoir des espaces ou des lignes vides dans ce code qui produisent un début de sortie avant que header() n'ai été appelé.

Il y a cependant deux entêtes spéciaux. Le premier est "Location". Non seulement il renvoie un entête au client, mais en plus, il envoie un statut de redirection à Apache. Du point de vue de l'auteur de script, cela importe peu, mais pour ceux qui connaissent les rouages internes d'Apache, c'est primordial.


<?php
header("Location: http://www.php.net");  /* Redirige le client vers le site PHP */
exit();  /* Assure que le code ci-dessous n'est jamais exécuté. */
?>
      

Le deuxième type d'appel spécial regroupe tous les entêtes qui commencent par "HTTP/" (la casse n'est pas importante). Par exemple, si vous avez votre page d'erreur 404 Apache qui pointent sur un script PHP, c'est une bonne idée que de vous assurez que le script PHP génére une erreur 404. La première chose à dans votre script est :


<?php
header("http/1.0 404 Not Found");
?>
	  

Les scripts PHP générent souvent du HTML dynamiquement, qui ne doit pas être mis en cache, ni par le client, ni par les proxy intermédiaires. On peut forcer la désactivation du cache de nombreux clients et proxy avec


<?php
  header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");             // Date du passé
  header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // toujours modifié
  header("Cache-Control: no-cache, must-revalidate");           // HTTP/1.1
  header("Pragma: no-cache");                                   // HTTP/1.0
?>
      

N'oubliez jamais que header() doit être appelée avant que le moindre contenu ne soit envoyé, soit par des lignes HTML habituelles dans le fichier, soit par des affichges PHP. Une erreur très classique est de lire un fichier avec include() ou require(), et de laisser des espaces ou des lignes vides, qui généreront un affichage avant que la fonction header() ne soit appelée. Le même problème existe avec les fichiers PHP/HTML standards.


<?php
require("user_logging.inc")
?>
<?php
 header ("Content-Type: audio/x-pn-realaudio");
?>
// Erreur :  Notez la ligne blanche ci-dessus
      

Voir aussi headers_sent().


User Contributed Notes: header


mnot@pobox.com
18-Apr-1999 12:12
All modern browsers and proxy caches will not require setting an exlicit Expires for dynamic content; PHP's lack of validators ensure that no content will be cached.
For more information, or to find out how to make PHP content cacheable, see http://www.pobox.com/~mnot/cache_docs/



bill@evil.inetarena.com
28-Apr-1999 11:04
Setting the File Name in a Download Dialog.
If you want to "suggest" a file name for a download to a browser, you can do this via the header:

header( "Content-type: application/x-gzip" );
header( "Content-Disposition: attachment; filename=some-file.tar.gz" );
header( "Content-Description: PHP3 Generated Data" );



chopin@csone.kaist.ac.kr
27-Aug-1999 02:41
Reading header of URL
php does not support reading header function. you must open socket directly. Following is the function to read URL header. (see http://www.phpwizard.net/phpTidbits/)

function get_headers($host, $path = "/")
{
$fp = fsockopen ("$host", 80, &$errnr, &$errstr) or die("$errno: $errstr");
fputs($fp,"GET $path HTTP/1.0\n\n");
while (!$end)
{
$line = fgets($fp, 2048);
if (trim($line) == "")
$end = true;
else
echo $line;
}
fclose($fp);
}



abo@minkirri.apana.org.au
27-Aug-1999 02:58
If you are just after header information using the above technique, surely it's better to use "HEAD" instead of "GET", as this will avoid transmission of all the content which doesn't need to then be striped out.



henning@sprang.de
16-Oct-1999 10:17
against the very first statement made above, that modern Browsers automatically reload dynamic content I've experienced it several times that IE5 cached dynamic pages and i had to do Shift-Reload to see how changes to my script affected the generated pages.


sba@networkers.dk
05-Nov-1999 09:07
I have experienced similar problems in IE5 with cached pages. Go to [Functions|Internet Settings|Temporary Internet Files|Settings] and change the "Check for new versions of previously cached pages" to "At every visit to the page". That will give you a little overhead initially, but will solve the problem..


ifedulov@outlook.net
01-Dec-1999 07:26
I hear somebody have problems with caching. Why then you just not put following tag into every single file in your site and everything will be fine:
<META HTTP-EQUIV="Expires" CONTENT="0">

That is it, every page will be for sure loaded from the site :)



alan@holotech.net
12-Dec-1999 12:21
Outputting the full HTTP header as suggested in the documentation:

header("http/1.0 404 Not Found");

causes a 500 error, at least in the version of Apache I'm using (1.3.3). Instead, use the Status header:

header("Status: 404 Not Found");



Pascal.Dufour@cdt.eu.int
15-Dec-1999 05:32
Answer to: ifedulov@outlook.net
> I hear somebody have problems with caching. Why then you just not put following tag into every
> single file in your site and everything will be fine: <META HTTP-EQUIV="Expires" CONTENT="0"> That
> is it, every page will be for sure loaded from the site :)

Your solution will work with browser cache but not with server cache (like squid) that do not "see"
the html content. Server cache relies on HTTP headers.



david@audiogalaxy.com
20-Feb-2000 11:04
RFC 2068 (HTTP 1.1 Specification) has been superceeded by RFC 2616 http://www.w3.org/Protocols/rfc2616/rfc2616.html See section 14 for definitions of HTTP headers.


j.clements@computer.org
27-Feb-2000 04:28
When a visitor chooses a new page on your site by clicking on a link you have set up, the link will include all the arguments required to identify what page to (create and) send. If the visitor uses a form to choose a page, the form variables are passed via the post method and don't appear in the "Location" header sent to the browser with the
requested page, so if the visitor bookmarks that page, the bookmark will lead back to your php3 file with no arguments given.

Here's how to use the "Location:" header to send all the information that is needed to enable the user to bookmark a particular page.

header ("Request-URI:
http://www.publicinfo.net/pic.php3?allvars=$allvars");

header ("Content-Location:
http://www.publicinfo.net/pic.php3?allvars=$allvars");

header ("Location:
http://www.publicinfo.net/pic.php3?allvars=$allvars");

If you send these headers in this order, it works! If you just send the "Location" header or send it first, the browser gets a 301 Found!, which is worse than useless.



nicolai@dufva.com
27-Feb-2000 08:39
This is not rocket science, but I add it to help others in the future.If you are trying to use for WML pages, you obviously first need to turn off the short tag style in the php ini file to enable XML source files, but to get the WAP browser to accept your page, add the following as the first line of your php file:

<?php header( "Content-type: text/vnd.wap.wml" ); ?>

Again, it may not be rocket science, but others might find it nice to have here in the manual (plus it makes be feel good, to contribute to this manual :-)



theo@darlings.net
06-Mar-2000 01:20
Header Targets:
Some guy wrote me and said that you can add a Window-target specification so it would be like
header("Location: http://www.mysite.com/ Window-target: _top");
or something like that.
He also said that it doesn't work with all browsers. I haven't tried it, so don't come yelling to me if it doesn't work.



peterNOSPAM@helpnet.com.au
08-Mar-2000 05:30
For Apache 1.3.9 W32, I had to replace
header("http/1.0 404 Not Found");
header("Location: http://www.php.net");
with
header("Status 301 Moved Permanently");
header("Location: http://www.php.net");



cck197@ecs.soton.ac.uk
18-Mar-2000 06:36
Here's a feature which you might want to be aware of, which has just cost me a lot of time:

I tend to use the define()/2 function like C pre-processor #defines. However, if you use this function to define HTTP headers, they get interpreted immediately! Here's an example:

define( "ARTICLE_MANAGEMENT", "Location: http://" . HOST . "/php/f1rumors/article_management.php3" );

At the top of my script causes an automatic redirection to article_management.php3 without ever calling header()/1. Be aware.



Zmegar@easynet.frZ
28-Mar-2000 02:55
As said above, the function
header("http/1.0 404 Not Found");

does not work. In fact, it only works when PHP is compiled as an Apache module (see source head.c)

It is better to use
header("status: 404 Not Found");

Because it always works whenever php is compiled as an Apache module or a standalone binary.

(Applies to php up to 3.0.15, i have not tested the later versions)

(remove the 'Z' in my email to answer me)



joe@aigraphics.com
28-Mar-2000 08:21
here us an example of a User Auth This is tried and proven on dtheatre.com:

if (!isset($PHP_AUTH_USER)) {
Header("WWW-Authenticate: Basic realm=\"Admin\"");
Header("HTTP/1.0 401 Unauthorized");
$REMOTE_USER = "";
$REMOTE_PASSWORD = "";
$PHP_AUTH_USER = "";
$PHP_AUTH_PW = "";
print "You hit cancel! if it was an accident please <a href=\"$PHP_SELF\">click here</a> to try again.";
exit;
} else if ((!$PHP_AUTH_USER == "user") && ($PHP_AUTH_PW == "pass")) {
print "You are unauthorized";
}



mu@mikrobit.com.pl
04-Apr-2000 12:59
WWW-Authenticate: works fine unless you're doing it once. Calling unset($PHP_AUTH_USER) gives no success and this variable is still visible for commands like: if (!isset($PHP_AUTH_USER) ).


lists@obira.de
18-Apr-2000 09:12
After several hours of wondering why IE5.0 doesn´t display my custom Errorpage i found the sollution in this article
http://support.microsoft.com/support/kb/articles/q218/1/55.asp
In short: The Errorpage needs to be larger than 512 Bytes.



fake-steve@fojar.com
26-Apr-2000 02:44
I encountered the following issue; maybe it's a known issue and I wasted a bunch of time.

If you're trying to force a page-reload using location: redirection, it won't work. you can only redirect to another page. i use one php script for a large and complicated web-based invoicing system, and ran into this problem when trying to fetch the next order from the queue when the user encountered an odd order. using location:, it would parse through to the end of the script and display a blank page, but redirecting to another one-liner that redirected back, it worked.

hope this helps someone else...



reb@wd3.com
08-May-2000 08:27
To clear out an authorized user....

If you use $PHP_AUTH_USER="" it will get rid of this problem.



webmaster@linko.com
21-May-2000 12:31
To Download files for valid name, try like this...

header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=yourfilename");
header("Content-Transfer-Encoding: binary");

but... when use IE5.0 to open files without download must select open two times..



luciano@netsolution.com.ar
24-Jul-2000 04:55
To make a PHP script open up a windows asking to download use this code:
header("Content-Type: application/download\n");
header("Content-Disposition: attachment; filename=\"file.tgz\"");
$fn=fopen("file.tgz" , "r");
fpassthru($fn);


This works for any file..

Luciano Ramos



steven@herod.net
27-Jul-2000 01:18
Note, calls to header in a particular order do not have any affect over the order in which they are actually output to the browsers, from Rasmus Lerdorf :
"PHP can't set the order of
headers. All PHP does it fill in the response header table and Apache
decides what order to send them in."

With Apache 1.3.4 this causes the code:

header("Content-type: text/html");
header("Content-Encoding: gzip");

Actually puts out:

Content-Encoding: gzip
[snip]
Content-Type: text/html

Enjoy!



brendan@essex.ac.uk
03-Aug-2000 05:51
Contrary to the examples, I found that
the HTTP/1.0 has to be in uppercase. This is using the header() command as the first line in a PHP file pointed to by Apache's ErrorDocument directive.

Server: Apache/1.3.9 (Unix) PHP/4.0.1pl2



philliptemple@yahoo.co.uk
10-Aug-2000 01:01
To all of those wanting to use Basic Authentication and are getting 'Internal Error' when using the line:

header('HTTP/1.0 401 Unauthorized');

Use instead: Header('status: 401 Unauthorized');

And everything will start working without changing the default Apache set-up.

Phillip.



jon@odp.co.uk
15-Aug-2000 07:36
I'm building a web-app in PHP and have had a nightmare with MSIE 4/4.5/5 cacheing pages which shouldn't be cached. I tried sending the correct headers, which works fine with Netscape but not MSIE. After several hours trawling through the MS developer support site I found a reference to a refresh bug in recent versions of MSIE, and this solution which appears to work fine. It involves a little JavaScript in addition to the correct headers:

&lt;?
header ("Pragma: no-cache");
header ("Cache-Control: no-cache, must-revalidate, max_age=0");
header ("Expires: 0");
?>

<HTML>
<HEAD>
<TITLE>Refreshes Every Time</TITLE>

<SCRIPT LANGUAGE="JavaScript">
function placebo() {}
</SCRIPT>

</HEAD>

<BODY onUnload="placebo()">

The page content

</BODY>
</HTML>

This isn't a PHP-specific issue so should also work fine with other approaches.
Hope this is useful, Jon.



ccampos@mail.com
17-Aug-2000 08:01
CUIDADO al usar:
Content-Disposition: attachment; filename=xxxxx.xxx
en IE ver. 4.01
ver (http://support.microsoft.com/support/kb/articles/q182/3/15.asp)

[Editor's note: See the URL above for information on the the inability of IE 4.0.1 to open a save dialog upon recieving the header indicated above]



tychay@qixo.com
16-Sep-2000 09:05
Use getallheaders() instead of this if you want to READ the request HTTP header, instead of write a HTTP header,


dale@vocalscape.com
21-Sep-2000 09:12
To get around a cookie not being set because of the location header try this:

&lt;?
setcookie("mycookie", "CookieVal");
?>
<script language=javascript>
<!--
window.location = "mypage.php";
//-->
</script>

Hope this helps ^_^



mbabcock@fibrespeed.net
22-Sep-2000 04:23
Speaking of cacheability, allowing your basic php documents to be cached for a short period is often a very good idea. For example, I have php files that simply interpret text files. They always give the same output, so they may as well be long-term cacheable. How to do this easily? I wrote a quick function called CacheControl (consider it under the GPL) based on information available at: http://www.mnot.net/cache_docs/
("How to make your documents work with web caches").

function CacheControl($maxage, $smaxage)
{
$Modified = "Last-modified: ".gmdate("D, d M Y H:i:s", time())." GMT";
$Expires = "Expires: ".gmdate("D, d M Y H:i:s", time() + $maxage)." GMT";
$CacheControl = "Cache-Control: must-revalidate, max-age=".$maxage.", ";
$CacheControl.= "s-max-age=".$smaxage;

Header($CacheControl);
Header($Modified);
Header($Expires);
}



mbabcock@fibrespeed.net
22-Sep-2000 04:24
Note: when calling the function above, the two variables are the length of time the file should be cached by browsers ($maxage) and by public caches ($smaxage) in seconds.


cedricshock@iname.com
24-Sep-2000 01:19
I have tried the following with both php3 and php4:

When sending lots of header data, an extra Content-Type: text/html and Connection: close are often sent by php.

PHP sends these headers when the content type hasn't been specified.
If you don't want the extra headers sent, you must send the Content-Type seperatly from the other headers. i.e.:

Header($LotsOfLinesOfHeaderData);
Header("Content-Type: $ContentType");

works, but

Header($LotsOfLinesOfHeaderDataIncludingContentType);

doesn't. Best of luck.



luksa@marand.si
09-Oct-2000 07:23
Everyone who is having problems with cacheing in PHP4 ("Data Missing" error in Netscape for example) and didn't get this error in PHP3 should set session.cache_limiter = public (in php.ini). If set to nocache, php4 sends no-cache headers, which wasn't the case in php3 (because there's was no native session support).


cwible@cwible.com
19-Oct-2000 07:34
For those of you having problems with caching, PHP4 (when compiled with session support) adds four headers to all responses! Pragma, Cache-Control, Last-Modified, and Expires. While the session functions can control these, there is now way to let the browser perform caching on it's own. If you want to change this, just change the following lines in ext/session/session.c and then recompile.

CHANGE:
#define ADD_COOKIE(a) sapi_add_heade(a, strlen(a), 1);

TO
#define ADD_COOKIE(a)



tim@timwarner.com
04-Nov-2000 01:05
I was having trouble pushing a file using:

header("Content-Disposition: attachment; filename=yourfilename");

I found that this line works best
header("Content-Disposition: filename=yourfilename");



jan.krutisch@hamburg.de
04-Nov-2000 04:36
speaking of pushing files using
that Content-Disposition:

The ways described in the annotations up to now have one problem: Almost any browser will show you a dialog like: "Do you want to download 'sendfile.php3' ?", and then prompt you with a file selector with the correct filename (e.g. "foobar.zip").

I have found (saw this on palmgear) that setting the url to the php file which should push the file up like this:

"sendfile.php3/foobar.zip"

well, don't ask me, but that displays the right filename in the dialog and also pushes the file exactly the way I wanted it to.



root@1az.net
06-Nov-2000 12:22
wap and php are possible with header(), (if anyone is still interested by WAP).

after a slight edition of your apache config file :
DirectoryIndex .wml
AddType application/x-httpd-php3 .wml

On your .wml file, just add first :
&lt;?
header('Content-type: text/vnd.wap.wml');
/* Your wap page around..*/
?>
<wml>
....
</wml>



kill-9@kill-9.dk
29-Nov-2000 08:52
header( "Content-type: application/x-gzip " );
Header("Location: $myfile");

Just download a file



st.n@gmx.net
30-Nov-2000 11:17
I think the example from joe@aigraphics.com is slightly wrong, although it
helped me a lot. (Thanks!) The parens in the last if statement are misplaced
and I don't see why you're setting $PHP_AUTH_USER et al to an empty value.
(There is an "exit" a few lines below anyway.) And the browser should also
get a 401 error when the password was wrong, so that the user can retry the
input. My script (which works fine for me) looks like this:

&lt;?php ob_start() ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html><head><title>some title</title>
</head><body>&lt;?php
# ... some other code ...

if(!( $PHP_AUTH_USER == 'luser' and $PHP_AUTH_PW == 'secret' ))
{
ob_end_clean();
Header('WWW-Authenticate: Basic realm="test"');
Header('HTTP/1.0 401');
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html><head>
<title>Authentication failed</title>
</head><body>
<h1>Authentication failed</h1>

Your user and/or password input was wrong.


To try again, please hit the "reload" button on your browser or
<a href="?&lt;?php
echo htmlspecialchars($HTTP_SERVER_VARS['QUERY_STRING'])?>">click here</a>.
&lt;?php
require( 'footer.php' );
echo '</body></html>';
exit;
}
ob_end_flush();

# ... some more other code ...
require( 'footer.php' );
?></body></html>



philip@thepr()jects.()rg
15-Dec-2000 03:00
A nice friendly tutorial that explains HTTP is as such :

http://www.stud.ifi.uio.no/~lmariusg/download/artikler/HTTP_tut.html



junk@markdonline.com
16-Dec-2000 06:31
an example of using header() to set a cookie, works better than setcookie() (it seems) based on what I read in the setcooki() notes:

header ("Set-Cookie: u=$u; expires=time()+43200; path=/;");



webmaster@digitalshrine.com
18-Dec-2000 05:38
I have yet to find a single version of Netscape (PC) that supports the header mentioned above to specify the file name when saving...

header( "Content-Disposition: attachment; filename=some-file.tar.gz" );

Even version 6 doesn't respond to this header. Why, isn't it a standard?



vrillusions@neo.rr.com
27-Dec-2000 08:17
In response to webmaster@digitalshrine.com's post, it does work with netscape. I just finished a download script and it gives lets me save it as a filename (I am using Netscape v4.75). You can verify this and download something from http://www.vrillusions.com/downloads.shtml. Here is what my basic setup looks like:

$file_ext = substr($file_filename, -4);
if($file_ext == ".txt") { $content_type = "text/plain"; }
else { $content_type = "application/octet-stream"; }

$full_file_path = $file_path."/".$file_filename;
header("Content-Type: $content_type");
header("Content-Disposition: atachment; filename=$file_filename");
header("Content-Length: ".filesize($full_file_path));
readfile($full_file_path);
exit();

now $file_filename is what I get when I access the datafile and is something like textfile.txt or application.exe or archive.zip etc. and the $file_path is the absolute directory (ie, /usr/home/files) so I can actually place the files from outside the webdirecotry, making it almoast imposible to leech. Just make sure any files that need to be viewed in ASCII (php, html, perl, txt, etc) have a content type of text/plain or it won't download right.



vrillusions@neo.rr.com
27-Dec-2000 08:23
hmm... Just noticed the difference between what I have and yours... If you'll notice in my version there is only one T in atachment. After noticing that, I tried it IE and it worked in there as well. So maybe whoever set that standard couldn't spell that well. :) Hope that helps


spam@schu.net
11-Jan-2001 12:18
While trying to get php to generate real media pointer files dynamicly, I found that IE doesn't like the caching lines in the header. It seems that you need to override the php default with the header function. See the example code below:

&lt;?
# Sample code that starts realplayer
# with file names from a DB.

Header ("Pragma: ");
Header ("Cache-Control: ");
Header ("Expires: ");
Header ("Content-Type: audio/x-pn-realaudio");

# insert DB code here

print "rtsp://host.com:554/$filename";

?>

I hope this saves someone some time!

schu



mcartmel@magian.com.au
17-Jan-2001 08:46
Got IE to only ask to save once when using headers like this...

header("Content-Type: doesn/matter\r\n");
header("Content-Disposition: filename=filename.ext\r\n\r\n");
header("Content-Transfer-Encoding: binary\r\n");

Not actually putting 'atachment' in the Disposition line seems to work better :/ Go figure...



timothy@midtel.net
21-Jan-2001 03:15
Hi, I'm responding to dale@vocalscape.com's suggestion of using javascript to redirect users. There is one major drawback to this, however. If the user attempts to use the 'Back' button from the destination page, the user won't go anywhere. This can get quite frustrating, and could cause users not to come back to your site. You would be better if you did:

setTimeout("window.location='destination.htm'",3000)

This will cause the browser to wait for three seconds, and then go to destination.htm. Now, when the user tries to use the 'Back' button, it will work.

Hope this is usefull.



johansen_emil@hotmail.com
22-Jan-2001 05:54
Make sure *NOT ONLY* to have eliminated blanks before included php scripts, but *ALSO* after the ?>!!!

E-)mil



michaelkeeley@hotmail.com
24-Jan-2001 05:15
If you are trying the header() function and getting a 'headers already sent' error, make sure that you save your script with UNIX style line endings. the CR/LF pair at the end of the shebang line causes php to start interpreting as HTML and sends the headers.


yasuo_ohgaki@hotmail.com
08-Feb-2001 11:08
Like above note, if you include file and have newlines after script end tag "?>". PHP will show "header already sent" warning also. Common knowledge for experienced users(?), but I spent time to figure it out.


 About Notes


Previous page
 HTTP
 Updated
Sun, 11 Feb 2001
headers_sent 
Next page





Who's responsible for this?
Top of this page

Site
Hosting:



Located in
United States
Elements of this website are subject to copyright.
Questions about installing or using PHP should be directed to one of the mailing lists.
Only questions about the website should be directed to webmaster@php.net.