PHP: header expires not working
Asked Answered
P

3

7

My PHP code:

$expires_date = date('D, j F Y H:i:s', strtotime('now + 10 years')) . ' GMT';           
header("Expires: $expires_date");
header('Content-type: text/javascript');

echo 'hello world';

When I check the response headers, I see this:

Expires:Thu, 01 Jan 1970 00:00:00 GMT

What am I doing wrong?

UPDATE:

Was just experimenting, but it seems that I can't even unset Expires via header_remove('Expires');. I still see the 1970 date.

UPDATE:

My response headers:

Cache-Control:private
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:74
Content-Type:text/javascript
Date:Wed, 17 Oct 2012 22:40:45 GMT
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Keep-Alive:timeout=5, max=98
Server:Apache/2.2.21 (Win32) PHP/5.3.9
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.9
Polyphemus answered 17/10, 2012 at 13:35 Comment(9)
Why the .htaccess tag. Where are you putting this code?Recoup
Have you checked for any other rule related in your web server that may be overriding the header you set in php? Have you cleared cache in your browser and/or cookies depending on your application? Also, have you checked your error messages, you are supposed to use date.timezone or date_default_timezone_set(). ByeFaro
The code is in PHP. It's tagged .htaccess since that's where headers, etc. are set.Polyphemus
My .htaccess is sets my resources to +10 years. So I am just mimicking it. Cache is cleared and have verified I was getting a 200 OK. date works just fine.Polyphemus
Can you share your mod_expires and .htaccess configuration?Recoup
The relevant part: ExpiresByType text/javascript "access plus 10 years". When the resource is downloaded from my server, this works. What doesn't seem to work is when I try to do it in PHP.Polyphemus
If you create code that is not of type text/javascript does it work? I wonder if something is going on between mod_expires and mod_php.Recoup
can you put content of your htaccess here?Artel
raw.github.com/kiphughes/.htaccess/master/.htaccessPolyphemus
S
5

look at your htaccess file:

<FilesMatch "\.(htm|html|php)$">
        Header set Expires "Thu, 01 Jan 1970 00:00:00 GMT"

        # TODO: Google.com's setting are the following
        # Expires -1
        # Cache-Control private, max-age=0
</FilesMatch>

it looks like your FilesMatch .php is overriding the .htaccess Content-Type:text/javascript rule and the PHP expires header because the script is a .php file.

Comment out this header expires in your .htaccess and see if the PHP header +10 year expires still gives the 1/1/1970 date

Symptomatic answered 26/10, 2012 at 6:32 Comment(6)
i just enabled mod_headers and added this rule to my htaccess, it does indeed superceed the php Expires headerSymptomatic
Didn't work for me. I'm using CodeIgniter, so my pages don't really have a ".php" extension anyway. The browser recognizes the resource as text/javascript. How did you test? Did you use a regular PHP file?Polyphemus
yes I copied the code snippet you had, verified that it gave the correct future date, then I saw your link to .htaccess file and I added the filesmatch rule and saw the same 1/1/1970. I just tested a url rewrite to remove the .php extension and it still gives the 1970 header date, so not having .php extension in your url doesnt mean its still not matching the rule... do you have any other htaccess files in your folders?Symptomatic
try this to be sure. go into httpd.conf, comment out the LoadModule mod_headers line, save, restart apache and check again. That should definitely either rule out mod_headers or tell you it is infact the problemSymptomatic
thanks for the bounty. You never responded though, did my last comment help correct your problem? If there is something else going on with your server i kinda wanna know just in case I run across any issues like this myself...Symptomatic
Haven't had a chance to look into it. I'll update when I can. Thanks!Polyphemus
K
2

You have formatting errors.

  • Use d instead of j
  • Use M instead of F
  • Use gmdate() instead of date()

From header definitions (14.21):

An example of its use is

 Expires: Thu, 01 Dec 1994 16:00:00 GMT

 Note: if a response includes a Cache-Control field with the max-
 age directive (see section 14.9.3), that directive overrides the
 Expires field.

HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value "0", as in the past (i.e., "already expired").

To mark a response as "already expired," an origin server sends an Expires date that is equal to the Date header value. (See the rules for expiration calculations in section 13.2.4.)

To mark a response as "never expires," an origin server sends an Expires date approximately one year from the time the response is sent. HTTP/1.1 servers SHOULD NOT send Expires dates more than one year in the future.

So you shouldnt send Expires with more than one year in the future. Instead to indicate never expires ommit the header or use Expires: -1.

Kessler answered 28/10, 2012 at 0:6 Comment(3)
Steven Sauders points out that this 1 year limit is merely a recommendation. Yahoo sets it to 10 years, I think. I'm interested in Expires: -1 though as I see Google using it.Polyphemus
header('Expires: -1'); and header_remove('Expires'); did nothing. The response headers still show Expires:Thu, 01 Jan 1970 00:00:00 GMT.Polyphemus
@Polyphemus It looks like server its forced to set that, try cache-control with max-age as a workaround.Kessler
W
1

Try use :

// To revalidate the headers again

header("Cache-Control: no-cache, must-revalidate");

// Then set expire date

header("Expires: Sat, 26 Jul 2011 05:20:00 GMT"); // Date to expire

it fixed my problem before

Wheeze answered 1/11, 2012 at 9:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.