Wednesday, September 01, 2010

Automating Resource Cache Busting in PHP

You quickly learn that if you have a CSS, JavaScript or other static resource, you need some way to occasionally bust the cache. That is, hard coding a URL such as:

 http://mysite.com/css/style.css

is a bad idea. Some browsers (Safari on Mac seems to always bite me) are especially resistant to picking up a file from anywhere but the cache.

One common solution is to use URLs like:

 http://mysite.com/css/style.css?xcache=12

You can change xcache whenever you'd like to force the browser to pickup a new version of style.css. In the past, I've used the following trivial PHP code to implement this.

function xcache() { return 12; }
...
<link... href='http://mysite.com/css/style.css?xcache=<?=xcache();?>' .../>

Ugly, but workable.

Things is, I often forget to increase the value of xcache to bust the cache. That, and changing the value of xcache requires a svn commit, as the file has changed.

Today, though, it hit me that there may be a more efficient way to handle this. All xcache needs to be is a stable, but increasing, number? Why not wire it into the file modification time of a frequently changing file?

Turns out, this is trivial to do. I can say:

 function xcache() {
   return filemtime(__FILE__);
 }

Now, to bust the cache, I merely touch the file that contains the definition of xcache(). This process is faster than an edit, and doesn't require a svn commit.

Naturally, this can be tweaked to wire the xcache into any file. Say:

function xcache() {
  return filemtime(dirname(__FILE__) . "/../css/style.css");
}

In the above case, anytime I publish a new style.css file, the cache will be busted.

While I haven't done it yet, I believe you could potentially wire this into watching a variety of files. All one would need to do is something along the lines of:

function xcache() {
  return max(filemtime(__FILE__), filemtime(dirname(__FILE__) . "/index.php"), ...);
}

Only time will tell if this strategy is really more valuable than a hard coded number. But most importantly, it was a good reminder that anytime you're doing something by hand, there's probably a way to automate it. Got to love software that programs itself.

No comments:

Post a Comment