Совсем недавно стала задача организовать кэширование данных. И получилась весьма удобная вещь. Реализацию смотри под хабракатом…
Описанный ниже абстрактный класс кладем к нашим моделям в папку Cache. В моём случае это /Default/Models/Cache/Abstract.php
Для работы необходимо иметь рабочую модель, например Default_Models_Products.
В папке Cache, относительно файла нашей модели, создаем класс Default_Models_Cache_Products со следующими свойствами $_className и $_nonCachedMethods:
В $_className указываем имя кэшируемого класса. $_nonCachedMethods не обязательное свойство, в нем мы перечисляем те методы, которые нам кэшировать не нужно.
Все обращения к классу Default_Models_Products заменим на Default_Models_Cache_Products, работаем с ним также как и с Default_Models_Products.
Например, в нашей моделе реализован метод getList.
Получить данные мы можем следующим образом:
Реализована также возможность вызова статических методов. Если метод getList является статическим:
вызвать его можно будет так:
Для очистки кэша реализован метод cleanCache(), при его вызове будет произведена очистка кэша, относящегося только к данной моделе, что может оказаться весьма полезным.
Про задание параметров $_frontendOptions и $_backendOptions можно почитать тут и тут
Получившийся класс весьма универсален и подойдет не только для моделей.
P.S. Уточнение. Спасибо Виктору(Yeah) за подсказку, этот класс не будет работать в версии php ниже 5.3. Поскольку магический метод __callStatic() появился именно с этой версией php.
Описанный ниже абстрактный класс кладем к нашим моделям в папку Cache. В моём случае это /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); } }
Для работы необходимо иметь рабочую модель, например Default_Models_Products.
В папке Cache, относительно файла нашей модели, создаем класс Default_Models_Cache_Products со следующими свойствами $_className и $_nonCachedMethods:
class Default_Models_Cache_Products extends Default_Models_Cache_Abstract { protected static $_className = 'Default_Models_Products'; protected static $_nonCachedMethods = array('addProduct'); }
В $_className указываем имя кэшируемого класса. $_nonCachedMethods не обязательное свойство, в нем мы перечисляем те методы, которые нам кэшировать не нужно.
Все обращения к классу Default_Models_Products заменим на Default_Models_Cache_Products, работаем с ним также как и с Default_Models_Products.
Например, в нашей моделе реализован метод getList.
class Default_Models_Products { ... public function getList() { ... return $list; } ... }
Получить данные мы можем следующим образом:
$productsModel = new Default_Models_Cache_Products(); $productList = $productsModel->getList();
Реализована также возможность вызова статических методов. Если метод getList является статическим:
class Default_Models_Products { ... public static function getList() { ... return $list; } ... }
вызвать его можно будет так:
$productList = Default_Models_Cache_Products::getList();
Для очистки кэша реализован метод cleanCache(), при его вызове будет произведена очистка кэша, относящегося только к данной моделе, что может оказаться весьма полезным.
Про задание параметров $_frontendOptions и $_backendOptions можно почитать тут и тут
Получившийся класс весьма универсален и подойдет не только для моделей.
P.S. Уточнение. Спасибо Виктору(Yeah) за подсказку, этот класс не будет работать в версии php ниже 5.3. Поскольку магический метод __callStatic() появился именно с этой версией php.
