Forum Moderators: coopster

Message Too Old, No Replies

Improving the cache mechnism for a dynamically constructed file?

PHP compiles the file via includes, how to automate a client cache refresh?

         

JAB Creations

7:21 pm on Mar 7, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have been seeing JavaScript errors caused by the fact that when I update things folks with the older cached version of the script file encounter the version conflicts, the way I currently have the JavaScript file cached is unfortunately flawed. The problem is it's been a minefield trying to figure out how to construct an automated and fast way to update the cache. Getting the modified date of a file seems to be very slow in PHP for some reason. On top of that the main JavaScript file (which includes all the scripting except for the onload event and some global variables) is a PHP file that includes about a dozen or so files. I'm looking for some direction to get me moving in the correct direction. Suggestions please?

- John

eelixduppy

9:32 pm on Mar 8, 2011 (gmt 0)



What do you have the cache expiration time set to? Perhaps just reducing the amount of time it will stay in their cache will make a significant difference without doing too much else. Also, you should set your javascript expiration time to the same as the files that depend on it, so they are refreshed in their cache at around the same time, hopefully creating minimal problems.

JAB Creations

10:46 pm on Mar 8, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the reply, I conquered this issue yesterday. :)

My goal was to have the first request HTTP 200, the second after say ten to thirty seconds request only from the client's hard drive, the third after two minutes respond as an HTTP 304, and after four minutes if I've updated the file to be an HTTP 200 with the client receiving the new version of the file. This along with the fact that many smaller files compose the main file makes it easy for me to work with my JavaScript though added complexity to the goal of correctly caching it. Here is the full script. Using Fiddler helped a lot. Here is the code...

- John

<?php
ob_start();
echo '//<![CDATA['."\n";

$file = array('file1.js','file2.js','file3.js','file4.js');
$latest = getlastmod();

foreach ($file as $key => $value)
{
$mod = filemtime($value);
if ($mod>$latest) {$latest = $mod;}
include($value);
}

echo '//]]>';

$buffer = ob_get_contents();
ob_end_clean();

$lastmod = gmdate('D, d M Y H:i:s',$latest);
header('Last-Modified: '.$lastmod.' GMT');

$exp0 = $latest + 120;//Two Minutes
$exp1 = gmdate('D, d M Y H:i:s',$exp0).' GMT';
header('Expires: '.$exp1);
header('Cache-Control: max-age=120');//Two Minutes

function cacheHeaders($lastModifiedDate)
{
if ($lastModifiedDate)
{
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModifiedDate)
{
header('HTTP/1.1 304 Not Modified');
die;
}
else
{
$gmtDate = gmdate('D, d M Y H:i:s\G\M\T',$lastModifiedDate);
header('Last-Modified: '.$gmtDate);
}
}
}

cacheHeaders($latest);

header('content-type:application/javascript');

ob_start('ob_gzhandler');
echo $buffer;
ob_end_flush();
?>

eelixduppy

12:46 am on Mar 9, 2011 (gmt 0)



Very nice, thanks for sharing. :)

JAB Creations

12:54 am on Mar 9, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You're welcome and there's an extra too! I have an external JavaScript file with administrative scripts (the server side scripting always checks permissions but still...) and I only allow the scripting to be served if it's an administrator however to do that you have to start the session...PHP negates some of the headers in doing so to counteract that you have to use session_cache_limiter('private_no_expire'); before declaring the session and you must declare the session before handling the headers.

- John