Getting caching objects if a fairly frequent task when dealing with performative web applications.
Standard approach
if (cache object is valid) Â {
return cached object
} else {
get fresh object (*)
save object into cache
return object
}
I don’t like that approach as there are a lots of LOC that wraps the only meaningful code (to get the fresh object).
Easier approach with PHP Closures (anonymous functions): one function call
$data= getWithCache(function(){
//calculate $freshObject
return $freshObject;
});
//use $data !!
Much easier, isn’t it ?
Implementation of the function (uses Zend_Cache)
/** Caches the return value of the passed function.
* Zend_registry 'cache' must be defined. By phpntips.com
*
* @param Closure $f anonymous function called when cache is not valid
* @param string $cacheID cache ID, reflection info are used if not specified
* @return mixed cached Object
*/
function getWithCache(Closure $f, $cacheID = null)
{
$cache = Zend_Registry::get('cache');
if ($cacheID === null) {
$cacheID = md5(serialize(Reflection::export(new ReflectionFunction($f), true)));
}
if ($cache->test($cacheID)) {
return $cache->load($cacheID);
} else {
$ret = $f();
$cache->save($ret, $cacheID);
return $ret;
}
}
A concrete example
$posts = getWithCache(function(){
$zsd = new Zend_Service_Delicious('elvis...', '...');
return $zsd->getAllPosts();
});
RSS Feed
Twitter
Posted in 
I really like this idea but you need PHP 5.3. Another way is to use exceptions:
function getResultCached() {
try {
return $this->readCache(“key”);
} catch (CacheMissException $cme ) {
$result = ..;
return $this->writeCache($result,$cme);
}
}
Now readCache throws a CacheMissException when the key is not found, and stores the cachekey in the exception so it can be reused by writeCache.
Hmm, I don’t know how to properly paste code here, but this is wat the cache functions look like:
protected function readCache($cache_key) {
$cached = $this->cache->get($cache_key);
if (isset($cached))
return $cached;
throw new CacheMissException($cache_key);
}
protected function writeCache($object,$cme) {
$this->cache->set($cme->getKey(),$object);
return $object;
}