Forum Moderators: coopster
is there a HTTP-compliant implementation of If-Modified-Since-, If-Match, If-None-Match, If-Range and so on?
I want my PHP-script to act exactly as if it was a static HTML-page delivered directly from Apache.
I think this isn't easy to implement, especially if you take also weak and strong validators into account.
Chris
Did you know you can use the PHP header() function to pass through any HTTP header you like?
If so, were you aware of any problems using it in relation to HTTP compliance?
An easy way to use the 'last modified' header is if you are using flat files and get the last modified time of the file (or a timestamp from a DB for example), and use that value as your last modified date.
You may have to change the value to GMT for accuracy, I'm not sure.
<?PHP header("Last-Modified: " . gmdate("D, d M Y H:i:s", getlastmod()) . " GMT");?> Returns something such as:
HTTP/1.1 200 OK
Date: Sun, 07 Aug 2005 13:27:26 GMT
Server: NOYB
X-Powered-By: PHP/4.3.11
Last-Modified: Sat, 06 Aug 2005 14:45:36 GMT
Connection: close
Content-Type: text/html Which is correct since I modified the page yesterday ;)
The hassle is to write a HTTP-compliant function, where (at least!) all the headers I mentioned above are implemented.
It should act like it was a static page delivered from Apache. And Apache does a bit more, than only setting one or two headers. Please have a look at the HTTP-RFC if you're not sure.
I went through a similar process a few months back trying to get dynamic content with static-looking URLs behave like a static page served by Apache. You can set Last-Modified and such easily enough, but you're doing the code equivalent of teaching a dog how to quack like a duck - dynamic dressed as static. Thing is, if the content is not changing rapidly, then instead of faking static content, it is best to generate static content and let Apache do all the work.
I have a few sites with rarely-changing content that I generate with PHP etc. installed on my local machine. Then I simply use wget to rip the local version of the site and generate the static pages, and upload the changed files. A more advanced method is for the application to generate the static page automatically each time the content is updated.
And I think your comparison with the dog and the duck doesn't fit here:
One scenario where it makes sense to deliver proper headers is when you've a forum like this one here and old topics are on page 15. They won't change any more, or only very very seldom. If Apache does this, PHP can do it also!
I don't know why it's so complicated, why there are weak and strong validators, why the last-modified-header isn't enough, but I want a HTTP-compliant solution! This will work with all Proxies also, it's not only because of search engines.
If no one else knows a ready to use solution, I'll write my own. There's a wiki-software, not mediawiki but a smaller one, they've a quite complex header-handling. I've seen it yesterday afternoon when I searched for this topic on Google. I've to find it again, maybe I can use this with little changes. I haven't looked at the Apache-source-code, I guess it's too complicated but maybe it could help.
Nevertheless, thank you for your answers so far.
So an HTTP compliant implementation of If-Modified-Since is to send it out from your client, not from your server, and then, depending on your last modified date, to either send out a 304 (not modified) or serve it up and send out a 200. See RFC 2616, section 14.25.
Is that what you mean? You're looking to parse the request headers and serve up appropriate status codes?
In that case, you're looking for apache_request_headers() [us2.php.net]
This would let you serve up the appropriate HTTP status codes.
Of course, If-modified-since or If-Match are request headers. But my script has to handle them correctly.
Example: I found some scripts on the net, which send 304 depending on If-modified-since or If-match. They're always setting the Last-Modified and ETag header in their answers. According to the RFC that's wrong.
There are many other intricacies in the RFC.
I'll write my own code, there's nothing ready to use I think.
Thank you all.
Have you looked into the PEAR HTTP_Header class?
[pear.php.net...]
It has methods for setting various response codes, but it's still up to you to parse out the request codes.]
I think this package might be what you're looking for though I haven't tried it:
The most difficult part on your end is figuring out when If-modified-since requests are still fresh, having some sort of date criteria attached to individual page results, or groups of pages. It sounds like you've got this part straight, though.
Once this is done, you just need to send out "Last-modified" headers (look it up for appropriate spelling, remember that the date has to be properly RFC-formatted - more info on the PHP date() page) -- and when an 'If-modified-since' request comes in that is newer than your current date criterium, you just send out a 304 - not - modified header -- again, look it up for spelling.
Once you're doing If-modified-since headers, you may as well send out E-Tag headers and give appropriate responses for 'If-none-match' headers, this is pretty much the same thing, except not date-based, but "key"-based - an id sent out with each page which changes when the page changes. The content of this key can be as simple as the unix timestamp of your age-date, or even the current unix timestamp. Just check the incoming E-tag content to your date criterium, and if it's newer than your current date criterium, it's just 304 - not - modified - thank - you - ma'am.
You and Encyclo are both right here - it isn't just a matter of adding a few lines of code to your site to make PHP do this right, but it certainly is worth it if you aren't constantly updating your information -- very web-friendly, faster page return, less bandwidth.
A very short article / code fragment on the subject is on [simon.incutio.com...] .