php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #8017 PHP ignores "If-Modified-Since" headers
Submitted: 2000-11-28 16:58 UTC Modified: 2002-06-18 11:58 UTC
From: jr-php at quo dot to Assigned:
Status: Closed Package: Feature/Change Request
PHP Version: 4.2.1 OS: Linux
Private report: No CVE-ID: None
 [2000-11-28 16:58 UTC] jr-php at quo dot to
PHP: 4.0.3p1
Apache: 1.3.14
Browser: IE 5.5 SP1

Because I want my PHP pages to be cached, my PHP script sends out a Last-Modified header (entire code follows):

<?php
Header ("Last-Modified: Mon, 27 Nov 2000 00:00:00 GMT");
?>
Test...

One would think that this would be enough to get a web browser to cache the page, but evidently it is not. Examining my web server's access log shows that each time the page is subsequently requested (e.g. by pressing Refresh), it sends back a "200 OK" response code instead of a "304 Not Modified" as it should. In other words, the server is sending back a fresh copy of the page every time.

However, if I do a similar thing using a CGI script, the server *does* send back "304" codes as it should (entire code follows):

#!/bin/sh
echo "Last-Modified: Mon, 27 Nov 2000 00:00:00 GMT"
echo "Content-Type: text/html"
echo ""
echo "Test..."

In both cases, an "If-Modified-Since" header is being sent to the server. Yet the PHP script appears to ignore it completely and send a fresh page, while the very simple CGI shell script doesn't.

P.S. At the bottom of this are transcripts of the HTTP requests for the PHP & CGI scripts. Notice how PHP sends back a fresh page even though the If-Modified-Since date is the same as the Last-Modified date.

P.P.S. I just noticed that this problem affects PHP's own web site too! The page http://www.php.net/ returns a Last-Modified header, but browsers receive a fresh copy of the page every time since If-Modified-Since is ignored.


--- PHP script ---

GET /test.php HTTP/1.0
If-Modified-Since: Mon, 27 Nov 2000 00:00:00 GMT

HTTP/1.1 200 OK
Date: Mon, 27 Nov 2000 20:41:29 GMT
Server: Apache/1.3.14 (Unix) PHP/4.0.3pl1
X-Powered-By: PHP/4.0.3pl1
Last-Modified: Mon, 27 Nov 2000 00:00:00 GMT
Connection: close
Content-Type: text/html

Test...


--- CGI shell script ---

GET /cgi-bin/test.cgi HTTP/1.0
If-Modified-Since: Mon, 27 Nov 2000 00:00:00 GMT

HTTP/1.1 304 Not Modified
Date: Mon, 27 Nov 2000 20:41:46 GMT
Server: Apache/1.3.14 (Unix) PHP/4.0.3pl1
Connection: close

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-11-29 11:52 UTC] jr-php at quo dot to
Closed since it doesn't appear to be a bug, but rather missing functionality in PHP.
 [2000-11-29 11:57 UTC] stas@php.net
moved to feature request
 [2002-06-17 13:20 UTC] hholzgra@php.net
it is in the responsibility of the application code
to check for If-Modified-Since conditions and to
send 304 Status codes,
as PHP itself can't know what the data you are 
going to produce looks like or whether it has
changed since the last request in advance
without executing your code

PS: whatever the CGI script you are refering to
does, i'm rather sure that it deals with that
itself, too 
 [2002-06-17 14:00 UTC] jr-php at quo dot to
(Changing back to 'Open' since you clearly misunderstood the request.)

> as PHP itself can't know what the data you are 
> going to produce looks like or whether it has
> changed since the last request in advance
> without executing your code

This is not about suppressing the execution of code. It's about PHP (mod_php) handling If-Modified-Since automatically in the same manner as CGI on Apache.

This is possible, too, because I posted a proof-of-concept patch to the list.

> PS: whatever the CGI script you are refering to
> does, i'm rather sure that it deals with that
> itself, too 

You're saying my 5 line /bin/sh CGI script somehow "deals" with If-Modified-Since headers? I think not...
 [2002-06-18 04:12 UTC] markonen@php.net
What kind of logic do you suggest PHP should use to 
determine whether the output of your script has indeed been 
modified since the IMS date sent by the user agent?

Hint: we don't cache script output internally, so there is 
NO WAY for us to do that.

As for www.php.net not returning 304 for you -- tough. It 
works for us. Some Internet Explorer versions have the 
unfortunate tendency of mangling the IMS date (ie. the IMS 
date is not the same as the Last-Modified date the UA 
received).

Because we follow the RFC 2616 recommendation of checking 
for an exact match between the IMS date and our internal 
Last-Modified date, the IMS negotiation mechanism we have 
in place for www.php.net doesn't work on such user agents.

Please check your user agent behaviour before concluding 
that this is a bug in PHP.
 [2002-06-18 11:06 UTC] jr-php at quo dot to
> What kind of logic do you suggest PHP should use to 
> determine whether the output of your script has indeed been 
> modified since the IMS date sent by the user agent?

Easy - compare any Last-Modified header against any If-Modified-Since request header. Just like Apache does when running any CGI script (be it PHP, Perl, Python, sh, or whatever).

See the past discussion on the mailing list:

http://marc.theaimsgroup.com/?t=97544892600002&r=1&w=2
http://marc.theaimsgroup.com/?t=97551909500005&r=1&w=2

And specifically, the little patch I posted:

http://marc.theaimsgroup.com/?l=php-dev&m=97553565420685&w=2

Granted, the Apache-specific ap_parseHTTPdate() call needs to be replaced with a portable PHP equivalent, but the patch proves that is indeed possible, and quite easy to do.

Again, all I'm suggesting is making If-Modified-Since headers be handled automatically *in the same manner* as CGI scripts. *Nothing more.* I don't really see a valid reason why mod_php PHP scripts shouldn't get If-Modified-Since handling by default, when CGI PHP scripts do. It is inconsistent.

> As for www.php.net not returning 304 for you -- 

I have no clue what www.php.net is doing these days, and it's not relevant anyway.

> Please check your user agent behaviour before concluding 
> that this is a bug in PHP.

It is not and never was my "conclusion" that this is a bug in PHP. Notice the category is "feature/change request".
 [2002-06-18 11:58 UTC] markonen@php.net
Well slap my ass and call me a bitch! I only realised your 
intent after I sent my previous comment.

Now that I understand your request, I can see that it is 
indeed implementable. However, my answer to the request 
remains the same.

Saving bandwidth is only a half of the intent of the IMS 
negotiation mechanism. The other half is saving the cost 
and latency of generating the response. This is why we want 
to keep the IMS negotiation in the application domain -- to 
enable PHP users to choose the actions they want to take 
based on the If-Modified-Since header.

On www.php.net, for example, we have a low-cost method of 
finding out the Last-Modified date without actually 
executing the whole script. This enables us save 
considerable CPU resources in the cases we send a 304 to 
the UA.

Implementing the kind of generalized mechanism for IMS that 
you are advocating would create the illusion among PHP 
users that this matter was "taken care of". This wouldn't 
help the bigger goal of getting users aware of the 
underlying mechanisms and how to use them.

I am in the process of writing this issue up in the PHP 
manual; that is my preferred fix. I've also scratched the 
surface of the complexities involved in this article: 
http://homepage.mac.com/marko/20020514.html

And now, I'll play the open/close ping pong again...
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Sun Jun 14 09:00:02 2026 UTC