📜 ⬆️ ⬇️

An interesting approach to model caching

The other day I received a task to implement caching in models. In discussions with colleagues, an interesting idea was born, in my opinion, an idea that I would like to put before you.

Implementing the idea on the Zend Framework :
1. All models are inherited from our class My_Db_Table_Abstract :
class My_Model_ModuleSettings extends My_Db_Table_Abstract

2. Which in turn is inherited from Zend_Db_Table_Abstract :
class My_Db_Table_Abstract extends Zend_Db_Table_Abstract

3. In the base for all models class My_Db_Table_Abstract we describe the magic method __call () :
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 the models in two ways :
1. Without caching, just referring to the method:
$result = $ this ->_life->getAll( 'Now!!' );

2. Caching by 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 works , in which the presence of the 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 result of executing the method to be different with different parameters of the method, I made hashing the parameters:
$argHash = md5(print_r($arguments));
This is perhaps the most ambiguous moment, because I can not say exactly how this may affect performance (when testing, an increase in load was not noticed). You can use different hashing functions (md5 (), sha1 () ..) and different ways of converting an array of variables to a string type (print_r (), var_dump (), implode ()).

2. The name of the cached file is of the form model_ClassName_MeModaDame_HashParameters , excluding the possibility of coincidence.

3. The cache is tagged with 'model' , 'className' and 'methodName' tags, which make cleaning easy to manipulate. Here, for example, 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 would very much like to hear your comments ... What are the disadvantages of this method? Does he have the right to life?

Source: https://habr.com/ru/post/72828/


All Articles