@@ -53,13 +53,159 @@ $pool->clear();
5353
5454## Implementation
5555
56- If you are writing a PSR-6 implementation you may want to use this library. It is recommended that your object
57- implementing ` CacheItemPoolInterface ` also implements ` TaggablePoolInterface ` . That same object should also use
58- the ` TaggablePoolTrait ` . The trait has two protected methods; ` generateCacheKey($key, array $tags) ` and
59- ` flushTag($name) ` .
60-
61- When implementing tags, all the cache keys will change because we have to generate new cache keys that depends on the
62- tags. You need to do two changes on the implementation of ` CacheItemPoolInterface ` . First, when ever you have a key and
63- an array of tags you need to generate a new cache key using the ` TaggablePoolTrait::generateCacheKey($key, array $tags) `
64- function. Second, you need to implement a protected ` CachePool::getTagItem($key) ` function that does not generare a
65- new cache key. This is used internally to store the tags.
56+ If you are writing a PSR-6 implementation you may want to use this library. The implementation is easy and will work
57+ with all PSR-6 caches.
58+
59+ ** Warning: All the cache keys will change because we have to generate new cache keys that
60+ depends on the tags. This will include keys that do not use tags.**
61+
62+ You need to do three changes on the implementation of ` CacheItemPoolInterface ` .
63+
64+ * Implement ` TaggablePoolInterface ` and use ` TaggablePoolTrait `
65+ * Use ` TaggablePoolTrait::generateCacheKey($key, array $tags) `
66+ * Implement ` CachePool::getTagItem($key) `
67+
68+
69+ ### Implement interface and use trait
70+
71+ The trait has two protected methods; ` generateCacheKey($key, array $tags) ` and ` flushTag($name) ` .
72+
73+ ``` php
74+ class Pool implements CacheItemPoolInterface, TaggablePoolInterface
75+ {
76+ use TaggablePoolTrait;
77+
78+ // ...
79+ }
80+ ```
81+
82+ ### Generate cache key
83+
84+ Your cache pool's ` getItem() ` probably look like this:
85+ ``` php
86+ public function getItem($key)
87+ {
88+ $item = $this->storage->fetch($key);
89+ if (false === $item) {
90+ $item = new CacheItem($key);
91+ }
92+
93+ return $item;
94+ }
95+ ```
96+
97+ You need to generate a new cache key that depends on the tags.
98+
99+ ``` php
100+ public function getItem($key, array $tags = [])
101+ {
102+ $taggedKey = $this->generateCacheKey($key, $tags);
103+ $item = $this->storage->fetch($taggedKey);
104+ if (false === $item) {
105+ $item = new CacheItem($key);
106+ }
107+
108+ return $item;
109+ }
110+ ```
111+
112+ You need to do the same with all functions that takes a cache key as argument.
113+
114+ ``` php
115+ public function hasItem($key, array $tags = [])
116+ {
117+ $taggedKey = $this->generateCacheKey($key, $tags);
118+
119+ return $this->storage->exists($taggedKey);
120+ }
121+ ```
122+
123+ Here is the list of functions you need to change:
124+
125+ * getItem
126+ * getItems
127+ * hasItem
128+ * clear
129+ * deleteItem
130+ * deleteItems
131+
132+ ### Implement CachePool::getTagItem($key)
133+
134+ The trait uses the cache as a key-value store. The key is the tag name and the value is a random id created by
135+ ` uniqid() ` . The way to access the cache is by a protected function ` getTagItem($key) ` . This function will be very similar to your
136+ ` getItem($key, array $tags = []) ` . The only difference is that the latter will call ` generateCacheKey() ` .
137+
138+ Consider your new ` getItem($key, array $tags = []) ` :
139+
140+ ``` php
141+ public function getItem($key, array $tags = [])
142+ {
143+ $taggedKey = $this->generateCacheKey($key, $tags);
144+ $item = $this->storage->fetch($taggedKey);
145+ if (false === $item) {
146+ $item = new CacheItem($key);
147+ }
148+
149+ return $item;
150+ }
151+ ```
152+
153+ You would need ` getTagItem($key) ` to look like this:
154+ ``` php
155+ protected function getTagItem($key)
156+ {
157+ $item = $this->storage->fetch($key);
158+ if (false === $item) {
159+ $item = new CacheItem($key);
160+ }
161+
162+ return $item;
163+ }
164+ ```
165+
166+ You could refactor the two so the final result will look like this:
167+ ``` php
168+ public function getItem($key, array $tags = [])
169+ {
170+ $taggedKey = $this->generateCacheKey($key, $tags);
171+
172+ return $this->getTagItem($taggedKey);
173+ }
174+
175+ protected function getTagItem($key)
176+ {
177+ $item = $this->storage->fetch($key);
178+ if (false === $item) {
179+ $item = new CacheItem($key);
180+ }
181+
182+ return $item;
183+ }
184+ ```
185+
186+
187+ ### Deleting tagged items
188+
189+ When you want to delete all items with a specific tag you should use the ` TaggablePoolTrait::flushTag($name) ` .
190+
191+ ``` php
192+ public function clear(array $tags = [])
193+ {
194+ if (empty($tags)) {
195+ // Flush everything
196+ return $this->storage->flush();
197+ }
198+
199+ // Flush the items related to a specific tag
200+ foreach ($tags as $tag) {
201+ $this->flushTag($tag);
202+ }
203+
204+ return true;
205+ }
206+ ```
207+
208+ The ` TaggablePoolTrait::flushTag($name) ` changes the tag cache key so next time you run
209+ ` TaggablePoolTrait::generateCacheKey($key, array $tags) ` you will get a different cache key back. This will not remove
210+ the items from the cache, which introduce a memory leak. That is why it is important to use memcached or redis, which
211+ automatically purges stale records.
0 commit comments