📜 ⬆️ ⬇️

Cache models

Most recently, the task has become to organize data caching. And it turned out very convenient thing. Realization see under habrakat ...

The abstract class described below is put to our models in the Cache folder. In my case, this is /Default/Models/Cache/Abstract.php

abstract class Default_Models_Cache_Abstract { protected static $_cache; protected static $_staticCache; protected static $_tags = null; protected static $_className = null; protected static $_nonCachedMethods = array(); protected static $_frontendName; protected static $_backendName; protected static $_frontendOptions = array(); protected static $_backendOptions = array(); public function __construct() { static::$_cache = null; static::$_staticCache = null; static::_init(); } public function __call($name, $arguments) { return static::_call($name, $arguments); } public static function __callStatic($name, $arguments) { return static::_call($name, $arguments, true); } protected static function _call($name, $arguments, $useStatic = false) { static::_init($useStatic); $cache = $useStatic ? static::$_staticCache : static::$_cache; if (in_array($name, static::$_nonCachedMethods)) { return call_user_func_array(array($cache, $name), $arguments); } $id = $cache->makeId($name, $arguments); if (!($result = $cache->load($id))) { $result = $cache->__call($name, $arguments); $cache->save($result, $id, static::$_tags); } return $result; } protected static function _initConfig() { static $inited = null; if (null === $inited) { if (null === static::$_className) { throw new Exception("You must provide a <code>protected static" . " \$_className = ...;</code> statement in your class!"); } static::$_backendName = 'File'; static::$_frontendName = 'class'; static::$_frontendOptions = array(); static::$_backendOptions = array(); $inited = true; } } protected static function _init($useStatic = false) { $ref = null; if ($useStatic && null === static::$_staticCache) { $ref = static::$_className; } elseif (null === static::$_cache) { if (!class_exists(static::$_className)) { require_once 'Zend/Loader.php'; Zend_Loader::loadClass(static::$_className); } $ref = new static::$_className; } if (null !== $ref) { static::_initConfig(); static::$_tags = array(static::$_className); static::$_frontendOptions['cached_entity'] = $ref; if (!empty(static::$_nonCachedMethods)) { static::$_frontendOptions['non_cached_methods'] = is_array(static::$_nonCachedMethods) ? static::$_nonCachedMethods : array(static::$_nonCachedMethods); } $cache = Zend_Cache::factory( static::$_frontendName, static::$_backendName, static::$_frontendOptions, static::$_backendOptions ); if ($useStatic) { static::$_staticCache = $cache; } else { static::$_cache = $cache; } } } public function cleanCache() { $ids = static::$_cache->getIdsMatchingTags(); foreach($ids as $id) { static::$_cache->remove($id); } static::$_cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, static::$_tags); } } 

To work, you must have a working model, for example, Default_Models_Products.
In the Cache folder, relative to our model file, create the Default_Models_Cache_Products class with the following properties $ _className and $ _nonCachedMethods:
 class Default_Models_Cache_Products extends Default_Models_Cache_Abstract { protected static $_className = 'Default_Models_Products'; protected static $_nonCachedMethods = array('addProduct'); } 

In $ _className we specify the name of the class being cached. $ _nonCachedMethods is not a required property; we list in it those methods that we do not need to cache.

All references to the Default_Models_Products class are replaced by Default_Models_Cache_Products, we work with it as with Default_Models_Products.
For example, in our model the getList method is implemented.
 class Default_Models_Products { ... public function getList() { ... return $list; } ... } 

We can get the data as follows:
 $productsModel = new Default_Models_Cache_Products(); $productList = $productsModel->getList(); 

The possibility of calling static methods is also implemented. If the getList method is static:
 class Default_Models_Products { ... public static function getList() { ... return $list; } ... } 

You can call it like this:
 $productList = Default_Models_Cache_Products::getList(); 

To clean the cache, the cleanCache () method is implemented; when you call it, the cache that belongs only to this model will be cleared, which can be very useful.
')
About setting the parameters $ _frontendOptions and $ _backendOptions you can read here and here

The resulting class is very versatile and is suitable not only for models.

PS Refinement. Thanks to Victor (Yeah) for the hint, this class will not work in the php version below 5.3. Since the magic method __callStatic () appeared with this version of php.

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


All Articles