9

Something, I think Apache, adds these HTTP headers to all responses generated by PHP scripts:

Expires:   Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  no-store, no-cache, must-revalidate, post-check=0, pre-check=0

This works ok for actual dynamic pages, but I have some page that, while generated by PHP, are mostly static, and I want the browser to cache them.

Is there a way in PHP to remove those headers from the response, and thus activate the browser's default caching rules, or if not, is there any value I can set them to that's equivalent with them being absent?

I would prefer not to set my own values, because I want the browser to use the same caching rules as for static resources that are served by Apache itself (without using mod_cache).

Bart van Heukelom
  • 43,244
  • 59
  • 186
  • 301

9 Answers9

7

For those particular files you could add header() calls that set those headers differently. ie. header("Expires: " . $currentDatePlus10);

header("Cache-Control: max-age=3600, must-revalidate")
Myles
  • 20,860
  • 4
  • 28
  • 37
  • If possible, I'd really like to remove the headers altogether, so that browser behaviour is exactly the same as for normal static files on an unconfigured server. – Bart van Heukelom Dec 21 '09 at 00:24
  • Since it happens outside of the PHP environment, short of digging around in Apache, overwriting with another value would be your best bet. I commonly will use ridiculous expiration dates for static content (read 10 years) to keep the content cached. – Myles Dec 21 '09 at 00:28
  • 1
    I'm concerned that if I set it to a date 10 years in the future, changes will actually not get picked up by users. – Bart van Heukelom Dec 21 '09 at 00:37
  • 4
    "Caching is easy; Expiration is hard" – nickf Dec 21 '09 at 00:45
  • What is often done is to include a file version in the file name, and change references to that when the file version changes. (pretty easy if your already using php). Something like site.css?v=2.3 or site-2.3.css and change the version numbers so browsers will re-cache it. – CodeJoust Dec 21 '09 at 00:46
3

First I'd check if it really isn't one of the php scripts that sets these headers.

register_shutdown_function('foo');
echo "test";

function foo() {
  flush();
  $c = "headers_list: \n  " . join("\n  ", headers_list());

  if ( function_exists('apache_response_headers') ) {
    $c .= "\napache_response_headers:";
    foreach( apache_response_headers() as $k=>$v) {
      $c.= "\n  $k=$v";
    }
  }
  $c .= "\n\n";
  echo '<pre>', $c, '</pre>';
}

Does this print something "usable" on your server?

VolkerK
  • 95,432
  • 20
  • 163
  • 226
  • 1
    I've done the research, and it appears PHP sets the headers when using the session functions. I looked around the relevant docs. There are ways to change the value of the headers, but not prevent them from being set. – Bart van Heukelom Dec 21 '09 at 21:41
  • 2
    Actually, setting session.cache_limit to "none" (undocumented value) solved it. See http://stackoverflow.com/questions/681115/cache-control-header-modified-by-php-session – Bart van Heukelom Dec 21 '09 at 21:50
  • 1
    Yeah, I wonder which PHP dev decided that would be a good place to put it. – Bart van Heukelom Dec 21 '09 at 23:06
  • 2
    `''` (empty) is apparently the correct value to use with `session_cache_limiter`, according to the docs. – David Oliver Aug 26 '14 at 17:23
  • Took me a while to find this out, but it's true, if `session.cache_limit` is set to anything other than `''`, the `Cache-Control` header gets *overwritten* by PHP on `session_start`. – Mahn Jan 30 '15 at 23:10
2

You can manually provide HTTP headers from PHP via the header() function.

I'd imagine that doing so ought to disable the web server's default header values.

Matt
  • 68,711
  • 7
  • 155
  • 158
Ben Karel
  • 4,591
  • 2
  • 26
  • 25
1

These cache headers are sent when you start using sessions and set to "nocache" by default; this makes sure each request gives consistent results.

For instance, if you have a cart system and your browser caches /add?product=xyz, it may not add the product again; this is probably not what you want.

Having said that, the default setting can be changed by either using session_cache_limiter() before session_start() or setting the corresponding session.cache_limiter configuration setting.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
1
header("Expires: Fri, 1 Jan 2038 05:00:00 GMT");

or some equally absurd time in the distant future. Remember to set your header values before any output has been sent, unless you're doing output buffering for your entire page.

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

WarrenB
  • 2,145
  • 3
  • 14
  • 18
0

If your pages are changing not to often you should consider using Etag headers, like this:

https://gist.github.com/oliworx/4951478

This is useful especially on slow connections (like mobile phones).

Hint: You should always check, what the browser is really loading, with the firefox addon "Live HTTP headers": https://addons.mozilla.org/de/firefox/addon/live-http-headers/

Oliver Kurmis
  • 58
  • 1
  • 5
0

suppress that of the cache can be made as follows: PHP Code:

header ( "Cache-Control: no-cache, must-revalidate"); / / HTTP/1.1
header ( "Expires: Mon, 1 Jul 1990 05:00:00 GMT"); / / Date in the past

if you want to automatically generate it, then you this here: PHP: session_cache_limiter() - Manual they

NullUserException
  • 83,810
  • 28
  • 209
  • 234
streetparade
  • 32,000
  • 37
  • 101
  • 123
0

There is likely somewhere in your code that has set these variables, as I can't find where they are inserted automatically by PHP anywhere, nor are they in any of my LAMP installations.

The only automatically generated header for my installs is X-Powered-By with the PHP version.

As you've said, from the docs they recommend saying header("Expires:"); to replace the old header, but header("Cache-control:"); just became Cache-Control: max-age=0 in my browser (so this is not what you're trying to do).

I'd recommend checking if these values come from a framework or setting you've changed, but it may be different across different versions of PHP / platforms you'd be running PHP on.

I'd check for ExpiresByType or ExpiresDefault directives in global configs, vhosts, pr .htaccess files or any blocks encapsulated in <IfModule mod_expires> or <IfModule mod_expires.c>

"I want the browser to use the same caching rules as for static resources that are served by Apache itself (without using mod_cache)."

Try looking at a static resource and then matching the rules then. You can calculate the Expires offest with this -> http://www.php.net/manual/en/function.header.php#93377

Dan Beam
  • 3,632
  • 2
  • 23
  • 27
  • I'm certain the headers are not set from within PHP. @"Try looking at a static resource and then matching the rules then. ": That's the point, they do not have these headers ;) – Bart van Heukelom Dec 21 '09 at 02:39
  • let me make this simpler for you, "is there any value I can set them to that's equivalent with them being absent?" not really. (blank) will be interpretted by each browser. "I would prefer not to set my own values" this is impossible as you or your host already have somewhere. – Dan Beam Dec 21 '09 at 03:03
  • Ok, I was certain the headers were not set by my code. Apparently though, they are set by PHP when you use it's sessions. See my comment @VolkerK – Bart van Heukelom Dec 21 '09 at 21:42
-1

I have not tried this but you could probably save such pages as .html files with your custom headers or lack of their-of and the script could run inside the

anijhaw
  • 8,954
  • 7
  • 35
  • 36