Forum Moderators: coopster

Message Too Old, No Replies

returning correct PHP last-modified header

any tips re: this code

         

jamie

11:11 am on May 24, 2003 (gmt 0)

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



hi,

i posted about something similar about two weeks ago but never got a reply. so i ploughed in myself:

to get the last-modified dates from
1) the main php script
2) any included scripts
3) the timestamp from a mysql database which is used to provide content.

then return the highest (most recent) of these values as the last-Modified header.

i have been unable to find any tutorial online explaining it fully, so i wrote this with help from zend and the php manual.

this following is included in every main php script:

<?php
$if_modified_since = preg_replace('/;.*$/', '', $HTTP_IF_MODIFIED_SINCE);

$mtime_child = filemtime('/usr/local/apache/sites/mydomain.com/htdocs/php/include.php'); // get time of included script(s)
$mtime = filemtime($SCRIPT_FILENAME); // get last-modified time of main script
$script_mod = gmdate('D, d M Y H:i:s', $mtime) . ' GMT'; // convert last-modified time of main script to normal DATE format
$mysql_mod = gmdate('D, d M Y H:i:s', $mysql_timestamp) . ' GMT'; // convert mysql timestamp to normal DATE format
$child_mod = gmdate('D, d M Y H:i:s', $mtime_child) . ' GMT'; // convert last-modified time of included script(s) to normal DATE format

$max_last_mod = max($mtime, $mysql_timestamp, $mtime_child); // find highest value to use for last-modified

$last_modified = gmdate('D, d M Y H:i:s', $max_last_mod) . ' GMT'; // convert last-modified to normal DATE format

if ($if_modified_since == $last_modified) {
header('HTTP/1.0 304 Not Modified');
exit;
}
header("Last-Modified: $last_modified"); // return most recent last-modified header
?>

this appears to works - but i am fairly new to php and wondered if anyone might have some tips on optimization, or other suggestions on what they use?

cheers

daisho

2:50 am on May 25, 2003 (gmt 0)

10+ Year Member



That looks good. Not sure why you need the regex at the top though.

Here is my super top secret caching header I use at the top of all my scripts. No MySQL in this one but it should be easy to add.

This also invokes ob_gzhandler which can save a lot of bandwidth.

The @clearstacache() is important since filemtime calls are kindof expensive so PHP caches them. But since we really want to know when the file is modified we must tell php to clear its cache.

daisho.

<?
/*
We want the newest timestamp between Header, Footer and curent file
to figure out what we use as the last modified time.
*/
@clearstatcache();
$self_time=filemtime($_SERVER['DOCUMENT_ROOT']."/".$_SERVER['PHP_SELF']);
$header_time=filemtime($_SERVER['DOCUMENT_ROOT']."/includes/header.php");
$footer_time=filemtime($_SERVER['DOCUMENT_ROOT']."/includes/footer.php");

$cache_time=($self_time>$header_time)?$self_time:$header_time;
$cache_time=($cache_time>$footer_time)?$cache_time:$footer_time;

$requested_time=strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);

header("Last-Modified: " . gmdate("D, d M Y H:i:s",$cache_time) . " GMT");

/*
We want to send a 304 Not Modified if our date matches the one they have on cache
*/
if( $cache_time==$requested_time ) {
Header("{$_SERVER['SERVER_PROTOCOL']} 304 Not Modified");
exit();
} else {
ob_start("ob_gzhandler");
}
?>

jamie

8:59 am on May 25, 2003 (gmt 0)

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



some great tips there daisho thanks!

i tried getting the $HTTP_IF_MODIFIED_SINCE with strtotime() but it never returns the correct value. so the preg_replace formats it to a value so i can compare it to the $last_modified.

strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) kept on returning Sun, 25 May 2003 00:00:00 or -1, so i left mine in which works?

i agree your way makes more sense as you deal with unix timestamps through the whole script except for when returning the actual header, but i couldn't get mine to work like that?

not to worry, the whole thing still works really well!

cheers