views:

41

answers:

2

I know how to set a basic expires HTTP response header in PHP as follows...

header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");

However, I want to make it a little more dynamic in that I want to, using PHP, specify an expiration time eight hours ahead of when the user accesses the content. Could someone help me achieve this?

Thanks in advance!

+1  A: 

Use strtotime to make a timestamp in the future, and gmdate to format it as a string in the GMT timezone.

define('EXPIRE_FORMAT', 'D, d M Y H:i:s T');
$expires = gmdate(EXPIRE_FORMAT, strtotime('+8 hours'));
header("Expires: $expires");
Emil Vikström
`strtotime()` is hideously slow compared to `$expires = gmdate(time() + 8*86400);` by a factor of ~7
Marc B
If the server is automatically sending an Expires response by default, can I override/null that out with a php script so that the expires header field is not set?
Drew2345
Marc B, you are of course correct. The call to strtotime can be exchanged for `time() + 8*86400` for those who like micro-optimization. time() is also "hideously slow" compared to $_SERVER['REQUEST_TIME'] ;-)
Emil Vikström
Drew2345, that probably depends on the server. Try!
Emil Vikström
+1  A: 

You can use Cache-Control’s max-age instead that indicated the number of second relative to the response time:

The expiration time of an entity MAY be specified by the origin server using the Expires header (see section 14.21). Alternatively, it MAY be specified using the max-age directive in a response. When the max-age cache-control directive is present in a cached response, the response is stale if its current age is greater than the age value given (in seconds) at the time of a new request for that resource.

An example:

header('Cache-Control: max-age=28800');

Note that if both Expires and Cache-Control’s max-age are present, max-age is preferred over Expires:

If a response includes both an Expires header and a max-age directive, the max-age directive overrides the Expires header, even if the Expires header is more restrictive.

Gumbo
Should I also set pragma?
Drew2345
@Drew2345: *Pragma* with what value?
Gumbo
I am not sure, that's why I am asking ;) I read http://www.mnot.net/cache_docs/#PRAGMA but am uncertain, given my above situation, what I should set this value to.
Drew2345
@Drew2345: Well, the [behavior for `Pragma: no-cache` in a response is not specified](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32): “Note: because the meaning of "Pragma: no-cache as a response header field is not actually specified, it does not provide a reliable replacement for "Cache-Control: no-cache" in a response.” So it’s quite useless. Use [`Cache-Control: no-cache`](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1) instead if you want a cached response not to be used by a cache without revalidation.
Gumbo
What about this: header('Cache-Control: private, max-age=28800, must-revalidate'); header('Expires:' . gmdate('D, d M Y H:i:s T', strtotime('+8 hours'))); header('Pragma: private');
Drew2345
@Drew2345: Well, *private* means the response is only cacheable by local caches and not by shared caches; *max-age* specifies the freshness lifetime; and *must-revalidate* requires the client to revalidate the cached entry. So a response may be cached by private caches only and must revalidate the cached response after it became stale (i.e. after the 28800 seconds). But the behavior of `Pragma: private` is not specified.
Gumbo