Skip to content

Commit ce23b3c

Browse files
committed
Merge pull request #8 from Nyholm/docs
Improved docs how you implement the trait
2 parents 838aca2 + 79b2332 commit ce23b3c

1 file changed

Lines changed: 156 additions & 10 deletions

File tree

README.md

Lines changed: 156 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)