
An interesting approach for caching models

Implementation of the idea on the Zend Framework :
1. All models are inherited from our My_Db_Table_Abstract class :
class My_Model_ModuleSettings extends My_Db_Table_Abstract
2. Which in turn inherits from Zend_Db_Table_Abstract :
class My_Db_Table_Abstract extends Zend_Db_Table_Abstract
3. In the class My_Db_Table_Abstract, which is basic for all models, we describe the __call () magic method :
public function __call($name, $arguments)
{
/** If call cached method */
if (preg_match('/^cached_(.+)$/', $name, $methodName)&&method_exists($this,$methodName[1])) {
/** Get cache instance */
$cache = My_Cache::getInstance();
/** Get arguments hash */
$argHash = md5(print_r($arguments, true));
/** Get model class name */
$className = get_class($this);
/** If method result don't cached */
if (!$result = $cache->load('model_'.$className.'_'.$methodName[1].'_'.$argHash)) {
$result = call_user_method_array($methodName[1], $this, $arguments);
$cache->save($result,
'model_'.$className.'_'.$methodName[1].'_'.$argHash,
array('model',$className,$methodName[1]));
}
return $result;
} else {
/** Generate exception */
throw new Exception('Call to undefined method '.$name);
}
}
Now we have the opportunity to use the methods of models in two ways :
1. Without caching, just referring to the method:
$result = $this->_life->getAll('Now!!');
2. Caching, adding the prefix “cached_” to the method name:
$result = $this->_life->cached_getAll('Now!!');
In the second case, referring to a nonexistent method, the __call () method is triggered , in which the presence of a cached result is checked. If the result of the method execution is cached, the cache is used; if not, the method is called and the result is cached.
Some nuances :
1. In order for the cache of the method execution result to be different with different method parameters, I made a hashing of the parameters:
$argHash = md5(print_r($arguments));
This is perhaps the most controversial moment, because I can’t say exactly how this can affect performance (during testing, no increase in load was noticed). You can use different hash functions (md5 (), sha1 () ..) and different ways to cast an array of variables to a string type (print_r (), var_dump (), implode ()). 2. The name of the cached file has the form model_ClassName_HashParameters_Name , excluding the possibility of a match.
3. The cache is tagged with the tags 'model' , 'className' and 'methodName' , which make it easy to manipulate cleaning. Here's an example of clearing the cache of all methods of the My_Model_ModuleSettings model :
$cache->clean(
Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
array('My_Model_ModuleSettings')
);
I'd love to hear your comments ... What are the disadvantages of this method? Does he have the right to life?