WordPress Caching, part 3: Custom Caching Library

When building Elemental (WordPress Theme) I decided to develop my own, very simple, caching plugin to help speed up the theme.

There were a few reasons why I did it but the main ones were:

  1. I was doing things with public apis that have an hourly request limit, so I had to build some sort of data cache.
  2. Whilst wp_super_cache and W3 Total Cache are well known there’s no guarantee people will use it.
  3. I thought it would be interesting to learn how.

My objectives when coding it were simple and follow my personal code desires. I wanted something small, clean, and fast – and hopefully I achieved all three.

BM_Cache Library

I ended up writing a library of functions that get and set cache values – and since I like to share I thought I would open it up. The library is just a series of functions and it can actually be repurposed for any PHP application really easily. Maybe others will find a use for it or, even better, offer improvements.

<pre style="height:500px;"><?php
/**
 * cachePut
 * Save Cache files to cache directory
 *
 * @param string $id cache key - unique string for saving and retrieving cache data
 * @param mixed $data data to save to cache
 * @return boolean
 */
function bm_cachePut ($id = '', $data = NULL) {

	// make sure required values are visible
	if ($id == '' || $data == NULL) {
		return FALSE;
	}
	if ($handle = @fopen(bm_cacheName ($id), 'w')) {
		fwrite($handle, serialize ($data));
		fclose($handle);
		return true;
	} else {
		echo '';
	}
	return false;

}

/**
 * cacheGet
 * Retreive the cache using the unique key specifying an expiration age so that the cache can be refreshed
 *
 * @param string $id cache key - unique string for saving and retrieving cache data
 * @param integer $expires time in seconds that the cache file can live for before being refreshed
 * @return array
 */
function bm_cacheGet ($id = '', $expires = 0) {

	if ($expires == 0) {
		$expires = BM_CACHE_TIME;
	}
	// add on random 10 percent of the expire time to add some randomness
	// will mean all caches on one page for same time frame do not expire at the same time
	$expires = $expires + ceil (rand (1, ($expires / 10)));
	$filename = bm_cacheName ($id);
	$filenameExists = file_exists ($filename);
	if ($filenameExists) {
		$age = (time() - filemtime ($filename));
		//echo '';
		if ($age

As you can see, it’s very straight forward. There are four functions and they fo the following:

  • bm_cachePut – This saves the specified data to a cache file with the specified key
  • bm_cacheGet – load the data for the specified cache key. Uses a time parameter to set how long the cached data should live for before being reset
  • bm_cacheName – This converts the cache key into the file name for the cached content
  • bm_cacheKill – Delete a cache file based upon it’s key

Usage

To make use of the cache library I created another function that “gets” the “content”. This function makes use of the WP_Http class that I wrote about recently.

<?php
function bm_getContent ($url, $cacheTime = 60, $prefix = 'getContent') {

	$cachename = $prefix . '_' . md5($url . $cacheTime);
	$content = '';
	if (!$content = bm_cacheGet($cachename, $cacheTime)) {
		$request = new WP_Http;
		$result = $request->request($url);
		if (!isset($result->errors)) {
			$content = $result['body'];
		}
		bm_cachePut ($cachename, $content);
	}
	if ($content != '') {
		return $content;
	} else {
		return FALSE;
	}

}
?>

To use it all you have to do is use the code below and it will automatically cache the request for 1 minute:

<?php $content = bm_getContent ('url_to_cache'); ?>

A real life example could be with the Yahoo! weather code I wrote about a few months ago.

<?php
function bm_getWeather ($code = '', $temp = 'c') {

	$file = 'http://weather.yahooapis.com/forecastrss?p=' . $code . '&u=' . $temp;

	$data = bm_getContent($file);

	$output = array (
		'temperature' => bm_getWeatherProperties('temp', $data),
		'weather' => bm_getWeatherProperties('text', $data),
		'weather_code' => bm_getWeatherProperties('code', $data),
		'class' => 'weatherIcon-' . bm_getWeatherProperties('code', $data),
	);

	return $output;

}

function bm_getWeatherProperties ($needle, $data) {

	$regex = '<yweather .="" :condition.=""></yweather>';
	preg_match($regex, $data, $matches);

	return $matches[1];

}
?>

How was it for you? Let me know on BlueSky or Mastodon

(Please) Link to this page

Thanks for reading. I'd really appreciate it if you'd link to this page if you mention it in your newsletter or on your blog.

Related Posts

08 Apr 2010

WordPress Caching, Part 1: The Basics

Caching (on the internet) is the act of storing computationally expensive calculations in a way that can be recovered very quickly with the smallest possible impact on the server.Or, in short, ‘speeding stuff up’.In this series of posts I will...
13 May 2010

6 Tips to Build Better WordPress Themes

If you want to make WordPress themes, for clients, to release for free or to sell, then there are a lot of factors you need to take into consideration. Below are some hints and tips that should help ease your...
16 Sep 2009

What’s new with the Elemental WordPress theme?

Elemental is the upcoming theme framework for Pro Theme Design. It’s been in development for absolutely ages, and the code is really showing it’s maturity, and I am really pleased with the possibilities it opens up.The focus when developing Elemental...
27 May 2013

WordPress: 10 Years Young, What Does The Future Hold?

WordPress is now 10 years old. I started using wordpress 9 years ago – which means I joined the WordPress community early on. The reason I chose WordPress is simply because of the fabled 5 minute install process – I...
29 Mar 2009

The future of WordPress themes

A couple of weeks ago there was quite a lot of talk within the WordPress themes community about the future of WordPress. Ian Stewart started it, and then it spread around the blogosphere… so I thought I’d offer my rather...
10 Mar 2010

Using the Yahoo Weather API (in your WordPress themes)

When developing our Hyperlocal WordPress theme called The Local Darren came up with the idea of adding the local weather to the themes header. After a bit of research I decided that the Yahoo! Weather api was the best solution.Before...