Simple PHP Caching and Content Retrieval Function

Written by David Walsh on Thursday, December 10, 2009


One way to make your website exponentially faster is by caching both remote and internal requests. Why request your RSS subscriber count from FeedBurner more than once a day if that count is calculated once per day? Why hit your database on each page load if that content rarely changes? I’ve created a primitive request-and-cache function for PHP that checks for fresh content in the cache and retrieves content from a source if fresh content isn’t available.

The PHP Function

/* gets the contents of a file if it exists, otherwise grabs and caches */
function get_content($file,$url,$hours = 24,$fn = '',$fn_args = '') {
	//vars
	$current_time = time(); $expire_time = $hours * 60 * 60; $file_time = filemtime($file);
	//decisions, decisions
	if(file_exists($file) && ($current_time - $expire_time < $file_time)) {
		//echo 'returning from cached file';
		return file_get_contents($file);
	}
	else {
		$content = get_url($url);
		if($fn) { $content = $fn($content,$fn_args); }
		$content.= '';
		file_put_contents($file,$content);
		//echo 'retrieved fresh from '.$url.':: '.$content;
		return $content;
	}
}

/* gets content from a URL via curl */
function get_url($url) {
	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5);
	$content = curl_exec($ch);
	curl_close($ch);
	return $content;
}

My get_content function accepts four arguments:

  • The file to grab content from. If the file doesn’t exist, the file is created and content placed into.
  • The URL to get content from if cached content isn’t fresh.
  • A function name to pass the freshly received content to.
  • Arguments to pass to the third argument’s function.

The function is, of course, very primitive. I like that my function handles both retrieval and caching so that I don’t need to repeat code whenever I want cached content.

Sample Usage 1

/* usage */
$TWITTER_FOLLOWERS_FILE_NAME = 'twitter-followers.txt';
$TWITTER_FOLLOWERS_URL = 'http://twitter.com/users/show.json?screen_name=davidwalshblog';

$TWITTER_FOLLOWERS = get_content($TWITTER_FOLLOWERS_FILE_NAME,$TWITTER_FOLLOWERS_URL,3,'format_followers',array('file'=>$TWITTER_FOLLOWERS_FILE_NAME));
/* utility function */
function format_followers($content,$args) {
	$content = json_decode($content);
	$twitter_subscribers = $content->{'followers_count'};
	if($twitter_subscribers) {
		$twitter_subscribers = number_format($twitter_subscribers,0,'',',');
		file_put_contents($args['file'],$twitter_subscribers);
		return $twitter_subscribers;
	}
}

The above code retrieves my Twitter follower count, parses the code, and caches the content for three hours.

There are several more advanced PHP caching classes available but the simple function above covers most of my needs — hopefully it can help you out too!


Epic Discussion

Commenter Avatar December 10 / #
Hervé says:

Why don’t you simply use something simple like pear cache lite ?

Commenter Avatar December 10 / #
Michael says:

Hi,
ever thought about memcached? Its a nice daemon, which can store such things in memcache, its very easy to usw and very efficient. Many big sites use it, facebook has about 800 Memcached-Servers.

Commenter Avatar December 10 / #
Chris the Developer says:

@herve + michael: Simply put, this approach allows the developer to cache without having to set the environment up to use memcache or pear cache lite….

Commenter Avatar December 10 / #
Brandon says:

Thank you! I was looking for something like this yesterday. Exactly what I needed.

Commenter Avatar December 10 / #

Basic caching like this is really useful when dealing with APIs, but I wish WordPress would add some centralized caching functions. It would make things neater than dumping data into assorted wp_options fields…

Commenter Avatar December 10 / #
Spyros says:

I must say that i like this blog very much. I’m pretty interested in mootools because i’m in the process of creating javascript UIs. This tutorial is also very nice. It’s a good habit to cache whatever is possible.

Commenter Avatar December 11 / #

Nice function.
I’ll be looking to build something similar, but with images created dynamically… Check if image exist and check if image is “recent”… else regenerate the image.

I allready did something similar with an XML generator, so users cannot spam the website to generate a new XML every time.

Caching is something useful when controlled… but can be a pain when you don’t know stuff is cached (ka-Map comes to mind…)!

Be Heard!

I want to hear what you have to say! Share your comments and questions below.

Name*:
Email*:
Website:  


© David Walsh 2007-2010. Contact David Walsh. Powered by the remarkable MooTools javascript framework.