Caching PHP pages

Page 1 - PEAR - Cache_Lite

Skip to navigation

PHP Extension and Application Repository
Apr
20

As your site traffic grows it takes longer and longer to generate a dynamic page from sending multiple queries to a database. One possible solution to limit queries is to cache the result of each query that is needed, or to have a complete full page cache for your site.

One thing I've found as this site has grown in size is that an increasing number of database queries fail simply because the database server isn't capable of holding up to all the traffic and can only allow a finite number of connections at any one time. The solution that I decided to use to solve this problem was to either cache queries, or to cache pages - the method would depend on what I could find available as their are basically two options here - use a third party caching solution, or to develop one myself. Lately I've been quite busy and haven't had the time to spend creating a way of caching so I decided the best option would be to see what was available first.

The first caching option I found was Cache_Lite which is part of the popular PEAR framework. One problem with this part of the framework is that it is no longer being actively maintained and is in need of someone to take it over. So any problems that are found with this are likely to go unfixed. Installing it is dead easy, especially if you already have PEAR installed - all you have to type into the BASH prompt in *nix is:

sudo pear install Cache_Lite

Once installed we can start using it in our PHP scripts to cache entire pages or just the result of queries. A requirement for each page cached is that it has a unique identifier - the easiest piece of information to use for this is the filename and the GET / POST string.

require_once 'Cache/Lite.php';

$query = 'SELECT * FROM `news` WHERE id=\''.$_GET['id'].'\';';

$cache = new Cache_Lite(array(
   'cacheDir' => '../cache/',
   'lifeTime' => 7200));
	
if ($newsItem = $cache->get($query)) {
}
else {
   $newsItem = query($query);
   $cache->save($newsItem, $query);
}

The above code demonstratres how we might store the result of a query to retrieve a news item and resuse it depending on whether it's still "in date" based on it only being cached for a maximum of 2 hours (lifeTime is measured in seconds). These result of this query will be stored in the /cache folder - preferably this should be somewhere that exists outside the publically viewable folder structure. The same principle can also be used for an entire page by using the output buffer effectively.

require_once 'Cache/Lite.php';

$cache = new Cache_Lite(array(
   'cacheDir' => '../cache/',
   'lifeTime' => 7200));
	
if ($data = $cache->get('samplePage')) {
}
else {
   ob_start();
   include('mysamplepage.php');
   $data = ob_get_contents();
   $cache->save($data, 'samplePage');
   ob_get_clean();
}

So instead of storing the result of a query we've used the output buffer to store whatever is printed to the screen from includingmysamplepage.php. This could be dynamic or static content generated from that. The contents of the buffer are then saved to the cache and the buffer cleared. Of course to actually see the page we would need to use print or echo(which is more efficient). So this seems a pretty good and flexible solution, but there are a few other still to look at.