📜 ⬆️ ⬇️

Caching in Yii using tags

Yii allows you to cache data in the form of an array returned directly from the database.
And the caching system has different dependencies. But none of these dependencies allows you to automatically track changes in the table without referring to it (I mean CDbCacheDependency), which is meaningless in a loaded system.

For such things came up with the so-called tagging. Those. some kind of tag is created, which is saved with all the caches associated with this table. And as soon as it changes, all related caches must reboot. As it turned out in Yii, this is done very simply.


')
It is worth mentioning that for more comfort Active Record is used.

It is done this way. Create a new dependency and save it, for example, in 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; } } } 


In the model we indicate when we will use the new dependency. Since we want to do this for the whole model, we add code to the beforeFind function:

 protected function beforeFind() { $this->cache(30, new CTagCacheDependency(get_class($this))); parent::beforeFind(); } 


Well, or wherever we want, the main thing here is "$ this-> cache (30, new CTagCacheDependency (get_class ($ this)));"



As a tag, we simply have the name of a class, a model associated with a particular table.

Well, when we delete or save something, we write in the right places (in the functions afterDelete, afterSave):

 Yii::app()->cache->set(get_class($this), microtime(true), 0); 




This way we update the tag associated with this model, and accordingly with the table. Now that the tag is updated as a result of updating the table, all caches with a dependency on this tag will have to be updated.

The default cache is used - component: cache. But you can specify your other.

Used Books:


UPD Important!

Updated CTagCacheDependency class code

Now the constructor takes the name of the Component as a string. For example:
 $this->cache($duration, new CTagCacheDependency(get_class($this), 'cache')); 


Made because of incorrect work with memcache.

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


All Articles