Yii позволяет кешировать данные в виде массива возвращаемые прямиком из базы данных.
А у системы кеширования есть разные зависимости. Вот только ни одна из этих зависимостей не позволяет автоматически отслеживать изменения в таблице без обращения к ней же (имею ввиду CDbCacheDependency), что в нагруженных системах бессмысленно.
Для подобных вещей придумали так называемое тегирование. Т.е. создается какой-то тег, который сохраняется со всеми кешами связанными с данной таблицей. И как только он меняется, все связанные кеши должны перезагрузиться. Как оказалось в Yii это делается очень просто.
Стоит упомянуть, что для большего комфорта используется Active Record.
Делается это так. Создаем новую зависимость и сохраняем ее, к примеру в components:
В модели указываем, когда мы будем использовать новую зависимость. Поскольку мы хотим это сделать для всей модели добавляем код в функцию beforeFind:
Ну или где хотим, главное тут — "$this->cache(30, new CTagCacheDependency(get_class($this)));"
В качестве тега у нас выступает просто название класса, модели, связанной с определенной таблицей.
Ну и когда мы удаляем или сохраняем что-то, пишем в нужных местах(в функциях afterDelete, afterSave):
Этим самым мы обновляем тег связанный с данной моделью, а соответственно и с таблицей. Теперь, когда тег обновится в следствии обновления таблицы, все кеши с зависимостью от этого тега должны будут обновиться.
Используется кеш по-умолчанию — компонент: cache. Но можно указать другой свой.
Используемая литература:
UPD Важный!
Обновил код класса CTagCacheDependency
Теперь конструктор принимает имя Компонента как строку. Например:
Сделано из-за некорректной работы с memcache.
А у системы кеширования есть разные зависимости. Вот только ни одна из этих зависимостей не позволяет автоматически отслеживать изменения в таблице без обращения к ней же (имею ввиду CDbCacheDependency), что в нагруженных системах бессмысленно.
Для подобных вещей придумали так называемое тегирование. Т.е. создается какой-то тег, который сохраняется со всеми кешами связанными с данной таблицей. И как только он меняется, все связанные кеши должны перезагрузиться. Как оказалось в Yii это делается очень просто.
Стоит упомянуть, что для большего комфорта используется Active Record.
Делается это так. Создаем новую зависимость и сохраняем ее, к примеру в components:
/** * CTagCacheDependency class. * * CTagCacheDependency represents a dependency based on a autoincrement(timestamp) of tags * * @author Roman <astronin@gmail.com> * @since 1.0 */ class CTagCacheDependency extends CCacheDependency { /** * @var autoincrement(timestamp) param is used to * check if the dependency has been changed. */ public $tag; /** * Cache component, by default used - cache * @var CCache */ public $cache; /** * Name of cache component, by default used - cache * @var string */ public $cacheName; /** * Constructor. * @param string $tag value of the tag for module */ public function __construct($tag=null, $cacheName='cache') { $this->tag=$tag; $this->cacheName = $cacheName; } /** * Generates the data needed to determine if dependency has been changed. * This method returns the integer(timestamp). * @return mixed the data needed to determine if dependency has been changed. */ protected function generateDependentData() { if($this->tag!==null) { $this->cache = Yii::app()->getComponent($this->cacheName); $t = $this->cache->get($this->tag); if ($t === false) { $t = microtime(true); $this->cache->set($this->tag, $t); } return $t; } } }
В модели указываем, когда мы будем использовать новую зависимость. Поскольку мы хотим это сделать для всей модели добавляем код в функцию beforeFind:
protected function beforeFind() { $this->cache(30, new CTagCacheDependency(get_class($this))); parent::beforeFind(); }
Ну или где хотим, главное тут — "$this->cache(30, new CTagCacheDependency(get_class($this)));"
- 30 — время хранения кеша, но лучше вынести это значение в переменную
- CTagCacheDependency — класс нашей новой зависимости
- get_class($this) — имя тега — имя модели
В качестве тега у нас выступает просто название класса, модели, связанной с определенной таблицей.
Ну и когда мы удаляем или сохраняем что-то, пишем в нужных местах(в функциях afterDelete, afterSave):
Yii::app()->cache->set(get_class($this), microtime(true), 0);
- 0 — бесконечное хранение
- get_class($this) — имя тега — имя модели
- microtime(true) — новое значение тега
Этим самым мы обновляем тег связанный с данной моделью, а соответственно и с таблицей. Теперь, когда тег обновится в следствии обновления таблицы, все кеши с зависимостью от этого тега должны будут обновиться.
Используется кеш по-умолчанию — компонент: cache. Но можно указать другой свой.
Используемая литература:
UPD Важный!
Обновил код класса CTagCacheDependency
Теперь конструктор принимает имя Компонента как строку. Например:
$this->cache($duration, new CTagCacheDependency(get_class($this), 'cache'));
Сделано из-за некорректной работы с memcache.