Simple File-Based PHP Caching
Sometimes dynamic elements of a page can slow down page loading or use too many resources for re-running the code every page load to be practical. The sidebar of this site touches four databases to pull up the stats it shows, and the counter I just added to the header gets its count from a remote XML API. Caching data or blocks of HTML with files is an easy solution.
The simplest way to cache the output of some PHP code you’ve already written is with output buffering and a file to store the cached HTML. Output buffering lets what would normally be sent to the browser, whether it’s text you’ve explicitly echoed, HTML or even binary data, be stored in a buffer instead. That buffer can then be assigned to a variable or read to the browser at any point in your code.
Here’s a commented example:
// check if the cache file already exists
// and is less than 5 minutes old
if (file_exists('cache.html')
&& time() - filemtime('cache.html') < 300) {
// the output is already cached, so just
// dump the file's contents to the browser
readfile('cache.html');
} else {
// otherwise, the cache doesn't exist yet
// or is more than 5 minutes old, so it's time
// to re-generate the content
// turn on output buffering so your code's output
// gets stored in the buffer instead of sent to the
// browser
ob_start();
// here you can place the existing PHP and HTML
// you want to cache
// now, write the output you captured in the buffer
// into the cache file
$fp = fopen('cache.html', 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
// and output the buffer's contents to the
// browser as well
ob_end_flush();
}
That’s all there is to it. Make sure the directory your script runs in has write access so the cache file can be created.
As another simple example, I recently decided to create a custom visit counter to sit alongside the Feedburner subscriber count in the header of this site. I made use of W3Counter’s API to get the current visit count. Unfortunately you won’t be able to try that out as well unless you’re willing to buy a paid account (starting at just $4.95/month) as free registrations are closed for a few weeks while I profile the performance and work on stabilizing load during peak hours.
W3Counter’s API takes requests as standard HTTP GET requests (URLs), and returns an XML response with the data. For this snippet, I used the “getWebsites” function to get a list of websites in my account, including their total visit and pageview counts. Since I only need one number out of the response, I didn’t bother firing up an entire XML parser, instead pulling the data out with a simple regular expression.
if (file_exists('count.txt')
&& time() - filemtime('count.txt') < 300) {
$count = file_get_contents('count.txt');
} else {
$xml = split("\n", file_get_contents("http://api.w3counter.com/xmlapi.php?request=getWebsites&key=xxxxxxxxxx&username=dangrossman"));
preg_match("#<uniqueCount>([0-9]*)</uniqueCount>#", $xml[112], $matches);
$count = $matches[1];
$file = fopen('count.txt', 'w');
fwrite($file, $count);
fclose($file);
}
A little CSS trickery aligns the count on a background image and the custom counter displays, updating every 5 minutes.
