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
StackOverflowNewbie
  • 39,403
  • 111
  • 277
  • 441
  • Why the .htaccess tag. Where are you putting this code? – Dave Oct 17 '12 at 13:40
  • The code is in PHP. It's tagged .htaccess since that's where headers, etc. are set. – StackOverflowNewbie Oct 17 '12 at 13:48
  • 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(). Bye – PatomaS Oct 17 '12 at 13:41
  • 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. – StackOverflowNewbie Oct 17 '12 at 13:50
  • Can you share your mod_expires and .htaccess configuration? – Dave Oct 17 '12 at 15:31
  • 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. – StackOverflowNewbie Oct 17 '12 at 21:56
  • 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. – Dave Oct 18 '12 at 13:30
  • can you put content of your htaccess here? – undone Oct 25 '12 at 17:06
  • https://raw.github.com/kiphughes/.htaccess/master/.htaccess – StackOverflowNewbie Oct 25 '12 at 21:09

3 Answers3

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

WebChemist
  • 4,393
  • 6
  • 28
  • 37
  • i just enabled mod_headers and added this rule to my htaccess, it does indeed superceed the php Expires header – WebChemist Oct 26 '12 at 06:36
  • 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? – StackOverflowNewbie Oct 26 '12 at 09:35
  • 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? – WebChemist Oct 26 '12 at 10:27
  • 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 problem – WebChemist Oct 26 '12 at 10:34
  • 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... – WebChemist Nov 03 '12 at 04:09
  • Haven't had a chance to look into it. I'll update when I can. Thanks! – StackOverflowNewbie Nov 03 '12 at 08:06
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.

Community
  • 1
  • 1
Zaffy
  • 16,801
  • 8
  • 50
  • 77
  • 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. – StackOverflowNewbie Oct 28 '12 at 04:18
  • `header('Expires: -1');` and `header_remove('Expires');` did nothing. The response headers still show `Expires:Thu, 01 Jan 1970 00:00:00 GMT`. – StackOverflowNewbie Oct 28 '12 at 04:22
  • @StackOverflowNewbie It looks like server its forced to set that, try cache-control with max-age as a workaround. – Zaffy Oct 28 '12 at 09:59
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

Omar Freewan
  • 2,678
  • 4
  • 25
  • 49