Skip to content

Commit 73c381a

Browse files
authored
Merge pull request #4 from moufmouf/classBoundCacheContract
Adding ClassBoundCacheContract
2 parents 0629e41 + f27cd3e commit 73c381a

File tree

5 files changed

+130
-2
lines changed

5 files changed

+130
-2
lines changed

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ $classBoundCache = new ClassBoundCache($fileBoundCache);
6060

6161
// Put the $myDataToCache object in cache.
6262
// If the FooBar class is modified, the cache item is purged.
63-
$classBoundCache->set('cache_key', $myDataToCache, FooBar::class);
63+
$classBoundCache->set('cache_key', $myDataToCache, new ReflectionClass(FooBar::class));
6464

6565
// Fetching data
6666
$myDataToCache = $classBoundCache->get('cache_key');
@@ -88,3 +88,28 @@ use TheCodingMachine\CacheUtils\ClassBoundMemoryAdapter;
8888

8989
$classBoundCache = new ClassBoundMemoryAdapter(new ClassBoundCache($psr16Cache));
9090
```
91+
92+
### Easier interface with cache contracts
93+
94+
You can even get an easier to use class bound cache using the `ClassBoundCacheContract`.
95+
96+
```php
97+
use TheCodingMachine\CacheUtils\FileBoundCache;
98+
use TheCodingMachine\CacheUtils\ClassBoundCache;
99+
use TheCodingMachine\CacheUtils\ClassBoundMemoryAdapter;
100+
use TheCodingMachine\CacheUtils\ClassBoundCacheContract;
101+
102+
$fileBoundCache = new FileBoundCache($psr16Cache);
103+
$classBoundCache = new ClassBoundMemoryAdapter(new ClassBoundCache($psr16Cache));
104+
$classBoundCacheContract = new ClassBoundCacheContract(new ClassBoundCache($fileBoundCache));
105+
106+
// Put the $myDataToCache object in cache.
107+
// If the FooBar class is modified, the cache item is purged.
108+
$classBoundCache->get(new ReflectionClass(FooBar::class), function() {
109+
// let's return the item to be cached.
110+
// this function is called only if the item is not in cache yet.
111+
});
112+
```
113+
114+
With cache contracts, there is not setters. Only a getter that takes in parameter a callable that will resolve the
115+
cache item if the item is not available in the cache.

src/ClassBoundCacheContract.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TheCodingMachine\CacheUtils;
6+
7+
use ReflectionClass;
8+
9+
class ClassBoundCacheContract implements ClassBoundCacheContractInterface
10+
{
11+
/** @var ClassBoundCacheInterface */
12+
private $classBoundCache;
13+
14+
public function __construct(ClassBoundCacheInterface $classBoundCache)
15+
{
16+
$this->classBoundCache = $classBoundCache;
17+
}
18+
19+
/**
20+
* @param string $key An optional key to differentiate between cache items attached to the same class.
21+
*
22+
* @return mixed
23+
*/
24+
public function get(ReflectionClass $reflectionClass, callable $resolver, string $key = '')
25+
{
26+
$cacheKey = $reflectionClass->getName() . '__' . $key;
27+
$item = $this->classBoundCache->get($cacheKey);
28+
if ($item !== null) {
29+
return $item;
30+
}
31+
32+
$item = $resolver();
33+
34+
$this->classBoundCache->set($cacheKey, $item, $reflectionClass);
35+
36+
return $item;
37+
}
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TheCodingMachine\CacheUtils;
6+
7+
use ReflectionClass;
8+
9+
interface ClassBoundCacheContractInterface
10+
{
11+
/**
12+
* @param string $key An optional key to differentiate between cache items attached to the same class.
13+
*
14+
* @return mixed
15+
*/
16+
public function get(ReflectionClass $reflectionClass, callable $resolver, string $key = '');
17+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace TheCodingMachine\CacheUtils;
4+
5+
use function clearstatcache;
6+
use PHPUnit\Framework\TestCase;
7+
use ReflectionClass;
8+
use function sleep;
9+
use Symfony\Component\Cache\Simple\ArrayCache;
10+
use TheCodingMachine\CacheUtils\Fixtures\A;
11+
use function touch;
12+
13+
class ClassBoundCacheContractTest extends TestCase
14+
{
15+
public function testClassBoundCacheContract()
16+
{
17+
$cache = new ArrayCache();
18+
$fileBoundCache = new FileBoundCache($cache, 'prefix');
19+
$classBoundCache = new ClassBoundCache($fileBoundCache, true, true, true);
20+
$classBoundCacheContract = new ClassBoundCacheContract($classBoundCache);
21+
22+
$val = 0;
23+
24+
$newVal = $classBoundCacheContract->get(new ReflectionClass(A::class), function() use (&$val) {
25+
return ++$val;
26+
});
27+
28+
$this->assertSame(1, $newVal);
29+
30+
$newVal2 = $classBoundCacheContract->get(new ReflectionClass(A::class), function() use (&$val) {
31+
return ++$val;
32+
});
33+
34+
$this->assertSame(1, $newVal2);
35+
36+
$classToTouch = new ReflectionClass(A::class);
37+
sleep(1);
38+
clearstatcache($classToTouch->getFileName());
39+
touch($classToTouch->getFileName());
40+
41+
$newVal3 = $classBoundCacheContract->get(new ReflectionClass(A::class), function() use (&$val) {
42+
return ++$val;
43+
});
44+
45+
$this->assertSame(2, $newVal3);
46+
}
47+
48+
}

tests/ClassBoundCacheTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ClassBoundCacheTest extends TestCase
2222
/**
2323
* @dataProvider touchFile
2424
*/
25-
public function testFileBoundCache($classToTouch)
25+
public function testClassBoundCache($classToTouch)
2626
{
2727
$cache = new ArrayCache();
2828
$fileBoundCache = new FileBoundCache($cache, 'prefix');

0 commit comments

Comments
 (0)