Cache_lite is a very usefull PEAR library for implementing lightweight caching mechanisims. Two things it is capable of doing is;
* caching the return from any function
* caching any datastructure you pass to it.
One issue with Cache_lites implementation of these two capabilities is that they come from different classes. If you need to cache a function return, you need to require Cache/Lite/Function.php first. If you want to cache a data structure, you need to require Cache/Lite.php prior. Also the function caching syntax seemed a bit unintuative to me.
To aleviate these issues I wrote a smaller wrapper class that unifies and symplifies the usage of the Cache Lite class(es).
This allows the client code of cache wrapper to simply call getCall(), getData(), and saveData() without needing to know that different base CacheLite classes are involved.
Also I put in a bit of code to allow for a bit of leway on the accepted formatting of function string parameters given to getCall();
Example Usage
For any function you want to add ‘cacheability’ to, you can add an optional param of…
$cacheTTL = CachWrapper::DEFAULT_CACHE_TTL
You then code similar to the first two lines of the exaple method below. Note you can supply a cacheTTL of 0 to essentually make an un-cahced call to the method.
/**
* File Contains class CacheWrapper
* @package licensing
* @subpackage utils
* @filesource
*/
/**
* Class CacheWrapper
* Puts a wrapper around CacheLite to reduce direct coupling and give
* a uniform interface to Cache_Lite and Cache_Lite_Function
*
* Usage example
* $cacheWrapper = new CacheWrapper(60*60*24);
* $countries = $cacheWrapper->getCall(‘Webwizard::call_secure’, array(‘WEB.EC.VALID.COUNTRIES’));
*
* @package licensing
* @subpackage utils
*/
class CacheWrapper {
private $cacheOptions;
private static $dataCacheEngine;
private static $callCacheEngine;
const PEAR_DIRECTORY = “/usr/lib/php”;
const DEFAULT_CACHE_TTL = 3600;
const DEFAULT_CACHE_FILE_DIR = “/tmp/”;
const DATA = ‘dataCacheEngine’;
const CALL = ‘callCacheEngine’;
/**
* Intantiate a CacheWrapper with a TTL and cache file save to dir
*
* @param int $lifetime The cache TTL
* @param string $cacheDir Dir to save the cache files to
*/
public function __construct($lifetime=self::DEFAULT_CACHE_TTL, $cacheDir = self::DEFAULT_CACHE_FILE_DIR) {
if ( ! class_exists(‘Cache_Lite’) ) {
ini_set( ‘include_path’,self::PEAR_DIRECTORY.’:’.ini_get(‘include_path’) );
}
self::$dataCacheEngine = null;
self::$callCacheEngine = null;
$this->cacheOptions = array (
‘cacheDir’ => $cacheDir,
‘lifeTime’ => $lifetime
);
}
/**
* Instantiates the appropriate CacheLite object.
* Only initializes the engine if it does not already exist.
* Note this is a private method
* – Cache_Lite
* – Cache_Lite_Function
*
* @param string $engineType
*/
private function initCacheEngine($engineType=self::DATA) {
if ($engineType==self::DATA && ( ! self::$dataCacheEngine) ) {
require_once(‘Cache/Lite.php’);
self::$dataCacheEngine = new Cache_Lite($this->cacheOptions);
} else if (! self::$callCacheEngine) {
require_once(‘Cache/Lite/Function.php’);
self::$callCacheEngine = new Cache_Lite_Function($this->cacheOptions);
}
}
/**
* cache the return value of a function call
*
* @param string $functionName The name of the function to call
* – Examples
* — Static Method of class [no params]
*
* $cacheWrapper = new CacheWrapper();
* return $cacheWrapper->call('WebWizAccessor::getCountries');
*
* — Static Method of class [w/ params]
*
* return $cacheWrapper->call('WebWizAccessor::getCountries',array(1,'hello'));
*
* @param array $arguments Array of the arguments for the function
* call
*/
public function getCall($functionName, $arguments = array()) {
$this->initCacheEngine(self::CALL);
$functionName = $this->formatForFunctionCall($functionName, $arguments);
return call_user_func_array( array(&self::$callCacheEngine,’call’),$arguments );
}
// Output buffer functions //
/**
* Get cached data
*
* A call to attempt to get previously cached data.
* If the cache file does not exist or the ttl has
* expired false is returned. Else the cached content
* is returned. Currently implementing PEAR Cache_Lite for the caching engine.
*
* @param string $cacheId Unique id used internally to track
* the cache file.
* @return string The cached data (FALSE if not found)
*/
public function getData($cacheId) {
$this->initCacheEngine(self::DATA);
return self::$dataCacheEngine->get($cacheId);
}
/**
* Save data to cache.
*
* Uses the cache engine to persist the data.
*
* @param mixed $data Data to cache
* @return boolean success of operation.
*/
public function saveData($data) {
$this->initCacheEngine(self::DATA);
return self::$dataCacheEngine->save($data);
}
/**
* Start output buffer caching
*
* to be implemented
*
*/
public function startData() {die(‘To be developed’);}
/**
* End output buffer caching
*
* To be Implemented
*
*/
public function endData() {die(‘To be developed’);}
/**
* Clear the all cache files from disk or if Group is given,
* all those within that group
*
* @param string $group The group to clear
* files for. Files not in group are left untouched. Only relates
* to output buffer cache.
*/
public function clearCache($group=null) {
$this->initCacheEngine(self::DATA);
self::$dataCacheEngine->clean($group);
}
public function removeData() {
die(“To be implemented”);
}
/**
* remove previously cached function/method call
*
* Forcefully removes a previously cached method/function call
*
* @param string $functionName The string name of the function to be removed.
* [leave off ()'s]
* @return void
*/
public function removeCall($functionName, $arguments = array()) {
$functionName = $this->formatForFunctionCall($functionName, $arguments);
$this->initCacheEngine(self::CALL);
$cacheId = ( ! self::$callCacheEngine->_fileNameProtection)
? md5(serialize($arguments))
: serialize($arguments);
self::$callCacheEngine->remove($cacheId, self::$callCacheEngine->_defaultGroup);
}
/**
* Remove all the method/function call files from the cache
*
* @return void
*/
public function removeAllCalls() {
$this->initCacheEngine(self::CALL);
self::$callCacheEngine->clean(self::$callCacheEngine->_defaultGroup);
}
/**
* helper function to format calls to cache_lite call.
* If this is a static class call ‘MyClass::function’, xform it to
* array(‘MyClass’,'function’) as expected by cache_lite_function->call
*/
private function formatForFunctionCall($functionName, &$arguments) {
$functionName = strstr($functionName,’::’) ? explode(‘::’,$functionName) : $functionName;
array_unshift($arguments,$functionName);
return $functionName;
}
}
