Forum Moderators: coopster

Message Too Old, No Replies

another last modified question

         

mihomes

7:27 am on Dec 27, 2006 (gmt 0)

10+ Year Member



So a while back I started parsing .htm/.html files as php so I could include some php code snippets within my pages while appearing as static pages.

With that I recently found that I no longer generate any cache headers.

I did some research and found that I can include :

<?php header("Last-Modified: " . gmdate("D, d M Y H:i:s", getlastmod()) . " GMT");?>

at the top of every page. I then validate this with a header check tool online with a few pages I was testing on. While the last modified date does show now it NEVER returns a 304 which is the entire purpose of this. It is ALWAYS 200.

Here is an example of my output from the test :

#1 Server Response: [foo.com...]
HTTP Status Code: HTTP/1.1 200 OK
Date: Wed, 27 Dec 2006 07:24:39 GMT
Server: Apache/1.3.36 (Unix) mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.4.2 FrontPage/5.0.2.2635.SR1.2 mod_ssl/2.8.27 OpenSSL/0.9.7a
X-Powered-By: PHP/4.4.2
Last-Modified: Wed, 27 Dec 2006 07:15:07 GMT
Connection: close
Content-Type: text/html

Now, shouldn't this be returning 304 to me after it has been cached locally on my machine?

Second question - is it worth creating an etag along with this? What about some of the other cache controls out there? Basically, my only reason for this currently is to comply a little better and save some bandwith. My pages rarely change, but when they ARE updated I would like places like Google to know about it.

mcibor

8:33 am on Dec 27, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Have you read
[php.net...]
?

DO NOT use this function unless you are absolutely sure both your Apache and PHP have been compiled with the same value for -DFILE_OFFSET_BITS.

If not, this function will return the access time (or maybe even garbage) instead of the modification time due do Apache and PHP using different versions of the stat structure.

This is true regardless of Apache and PHP version.

To be on the safe side, always use the workaround already posted below:
filemtime($_SERVER['SCRIPT_FILENAME'])

Happy New Year
Michal Cibor

mihomes

8:43 am on Dec 27, 2006 (gmt 0)

10+ Year Member



Thank you Michal! I now have :

<?php header("Last-Modified: " . gmdate("D, d M Y H:i:s", filemtime($_SERVER['SCRIPT_FILENAME'])) . " GMT");?>

which is properly returning the last modified date of the page. I checked this as well.

I still am receiving the 200 code EVERY time. I did some research and it appears I need to check my last modified time against the IfModifiedSince that is sent to me then return the proper header (304) or default (200).

Can anyone throw up some quick code? I've been looking on the forum and while there are lots of topics about this nobody has posted a simple yet correct solution to this.

mihomes

1:06 am on Dec 28, 2006 (gmt 0)

10+ Year Member



Anyone? I know there are more people with PHP using this out there...

mihomes

2:06 am on Dec 28, 2006 (gmt 0)

10+ Year Member



Okay, I think I came up with something and from testing and viewing my logs it appears to work correctly. If anyone would like to comment on any mistakes or changes I would appreciate it.

I call the following at the top of every page :

<?php include($_SERVER['DOCUMENT_ROOT']."/cache.php");?>
<?php doConditionalGet(gmdate("D, d M Y H:i:s", filemtime($_SERVER['SCRIPT_FILENAME'])) . " GMT");;?>

cache.php consists of :

<?php
//---------------------------------
// doConditionalGet function definition
//---------------------------------
function doConditionalGet($timestamp) {
// Create ETag from last modified date
$etag = '"'.md5($timestamp).'"';

// Send the headers
header("Last-Modified: $timestamp");
header("ETag: $etag");
header('Cache-Control: public');
header('Expires: '.gmdate('D, d M Y H:i:s', strtotime('+1 month')).' GMT');

// If browser provided IMS and ETag, get them
// Otherwise, set variable to 'false'
$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])?
stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH'])?
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;
if (!$if_modified_since &&!$if_none_match) {
return; }

// If at least one value exists, validate them
if ($if_none_match && $if_none_match!= $etag) {
return; // ETag exists but doesn't match
}

if ($if_modified_since && $if_modified_since!= $timestamp) {
return; // IMS exists but doesn't match
}

// Nothing has changed since last request
// Return a 304 and do NOT run the rest of page
header('HTTP/1.1 304 Not Modified');
exit;
}
?>

Comments please before I add this code to all my pages...

AlexK

3:52 am on Dec 28, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



mihomes:
I've been looking on the forum and while there are lots of topics about this nobody has posted a simple yet correct solution to this.

I beg to differ.

Check out Conteg content-negotiation Class [webmasterworld.com]. Whilst this is hardly "quick code" (it's 93k) usage is as simple as can be:

$param= array(
'modified'=> $mdate // (Unix timestamp)
);
$Encode= new Conteg( $param );

mihomes

4:39 am on Dec 28, 2006 (gmt 0)

10+ Year Member



Little more than I need it looks like plus, and no offense, if I can do something myself I'd rather not pay.

All I need is correct etag and if modified... I have no problem including a few lines at the top of each page to get the solution.

AlexK

4:14 am on Dec 29, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



mihomes:
no offense, if I can do something myself I'd rather not pay

Erm, the link posted (v0.12.2) costs nothing but a click. (?)

mihomes

4:47 am on Dec 29, 2006 (gmt 0)

10+ Year Member



Well, I followed the link, went to the website, and you need to become a member (which is free), but then you need to pay for bandwith or something to download. If there is a free download please point the way.

henry0

1:08 pm on Dec 29, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I built something else
any modif triggers the addition of one letter in a simple text file
if mofitied (the txt file) then modif was performed.
the rest is simply to display today's date.

AlexK

2:15 pm on Dec 29, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



mihomes:
If there is a free download please point the way

There is. It is on the first line of the link already posted [webmasterworld.com].

Since you missed it, here it is again, flagged a little more obviously this time:

--- This is the free download link --->

version 0.12.2 of Conteg is available for download [modem-help.freeserve.co.uk]

<--- That was the free download link ---

If you have any queries on usage of the Class, please send a cheque to.. er, no, I meant to say, please post your question into the relevant thread [webmasterworld.com].

PS
The no-cost-to-you download link above is located upon a no-hosting-cost ISP called 'Freeserve', located in the UK. I got a 15 MB website with them in 1999 (later increased to 30MB). They were taken over by Wanadoo, then recently tranferred to Orange. Orange has silently dropped the maximum website size back down to 15MB, which has prevented me from updating the free-download beyond the currently-posted v0.12.2.

mihomes

8:20 am on Dec 31, 2006 (gmt 0)

10+ Year Member



Thanks Alex. The latest version is the one I was referring to when I noticed the pay thing.

I took a look and it seems really nice although I dont quite understand the installation and implementation of it - not all too familiar with heavy php.

For instance, all I really want to do is show the last modified, if modified, and etags. My pages are all .htm/.html but I set them up to parse as php so I can include some php scripts and still appear as static pages. Do you have any walk through instructions for a newbie to implement that?

AlexK

2:18 am on Jan 1, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Your reply is at the Conteg thread [webmasterworld.com].

Please note that the previous thread referred to at the bottom of the reply stretches across more than one page.