skrip42 / cachelayer-bundle
Symfony 缓存层包
v1.2.7
2020-11-19 06:06 UTC
Requires
- php: ^7.1
- doctrine/common: ^2.7|^3.0
- ocramius/proxy-manager: ^2.0
- symfony/config: ^4.2|^5.0
- symfony/dependency-injection: ^4.1|^5.0
- symfony/http-kernel: ^4.3|^5.0
README
服务缓存层
安装
- 运行
composer require skrip42/cachelayer-bundle
基本用法
实现缓存接口
//redis cache example namespace App\Services\Cache; use Skrip42\Bundle\CacheLayerBundle\CacheInterface; use App\Services\Redis; class RedisCache implements CacheInterface { private $client; /** @required */ public function setRedisClient(...) { //inject you redis client } /** * Check is cache exist value * * @param mixed $instance request service instance * @param string $method request method * @param array $params request params * @param array $attr custom attribute * * @return bool */ public function has( $instance, string $method, array $params, array $attr ) : bool { return $this->client->exists( $this->getKey($instance, $method, $params) ); } /** * Get value from cache * * @param mixed $instance request service instance * @param string $method request method * @param array $params request params * @param array $attr custom attribute * * @return mixed */ public function get( $instance, string $method, array $params, array $attr ) { return unserialize($this->client->get( $this->getKey($instance, $method, $params) )); } /** * Set data to cache * * @param mixed $instance request service instance * @param string $method request method * @param array $params request params * @param mixed $data service return value * @param array $attr custom attribute */ public function set( $instance, string $method, array $params, $data, array $attr ) { $ttl = empty($attr['ttl']) ? 0 : $attr['ttl']; $this->client->setex( $this->getKey($instance, $method, $params), $ttl, serialize($data) ); } /** * Clear cache * * @param mixed $instance request service instance * @param string $method request method * @param array $params request params * @param array $attr custom attribute */ public function clear( $instance, string $method, array $params, array $attr ) { $pattern = get_class($instance) . '::' . $method . '*'; $pattern = str_replace('\\', '\\\\', $pattern); //escape '\' $keys = $this->client->keys($pattern); $this->client->del($keys); } public function getKey($instance, string $method, array $params) : string { return get_class($instance) . '::' . $method . '[' . serialize($params) . ']'; } }
使缓存服务公开
App\Services\Cache\RedisCache: public: true
将目标服务标记为可缓存
App\Services\TargetService: tags: [skrip42.cachelayer]
为目标服务方法添加注解
/** * @Cache( * RedisCache::class, * attribute = { * "ttl" = 900 * } * ) */ public function foo(...) { //do something }
附加功能
缓存链
您可以添加多个缓存注解,缓存将按照指定的顺序执行
/** * @Cache(LocalCache::class) //execute first * @Cache(RedisCache::class) //if LocalCache exist value, RedisCache will not be called */ public function foo(...) { .....
自定义属性
您可以定义将传递给所有缓存方法的附加属性
/** * @Cache( * RedisCache::class, * attribute = { * "ttl" = 900 //this attribute will be passed to all method of RedisCache * } * ) */ public function foo(...) { .....
忽略参数
您可以指定在缓存过程中将被忽略的参数
/** * @Cache( * RedisCache::class, * ignore_params = { * "param" * } * ) */ public function foo(bool $param) // the cache for foo (three) is the same as for foo (false) { .....
条件执行
您可以指定在什么条件下缓存将被执行
/** * @Cache( * RedisCache::class, * condition = { * "nocache" = false // execute only if $nocache = false * } * ) */ public function foo(bool $nocache = false)
缓存清理器
您可以指定清理缓存的策略
/** * @Cache( * RedisCache::class, * attribute = { * "target" = "getData" * } * action = "clear" //cache chear method will be called when setData is called * ) */ public function setData(...)
如果您想清理另一个方法(例如设置方法)的缓存,您可以添加具有方法名称的属性,并修改您的缓存类如下
public function clear( $instance, string $method, array $params, array $attr ) { if (!empty($attr['target'])) { $pattern = get_class($instance) . '::' . $attr['target'] . '*'; } else { $pattern = get_class($instance) . '::' . $method . '*'; } ...
缓存更新
您可以指定更新缓存的策略
/** * @Cache( * RedisCache::class, * action = "actualize" //cache chear method will be called when setData is called * ) */ public function setData(...)
条件清除和更新
您可以指定在什么条件下缓存覆盖操作
/** * @Cache( * RedisCache::class, * actualize_condition = { //cache willbe actualize when foo is called eitch $actualize = true parameters * "actualize" = true * }, * clear_condition = { //cache chear method will be called when foo is called witch $clear = true parameters * "clear" = true * }, * ignore_params = { * "clear", "actualize" * } * ) */ public function foo(bool $clear, bool $actualize) { ......
重新缓存方法
您可以指定在清除缓存后自动调用的重新缓存方法
```php /** * @Cache( * RedisCache::class, * attribute = { * "target" = "getData" * } * action = "clear", * recache_method = "recacheData" // recacheData(...) will be called after cache clear * ) */ public function setData(...)
CacheManager 和 CacheAccessor
CacheAccessor 允许您直接控制特定服务的缓存
要获取 CacheAccessor,请使用静态 CacheManager
use Skrip42\Bundle\CacheLayerBundle\CacheManager; use App\Services\SomeClass; ...... $cacheAccessor = CacheManager::getBy(SomeClass::class); //return CacheAccessor instance
⚠️ 如果您没有使用单例服务,您只能为最后一个服务实例获取 CacheAccessor;
CacheAccessor 的签名
class CacheAccessor { has(string $methodName, array $params = [], array $attr = []) : bool; find(string $methodName, array $params = [], array $attr = []) : array; //return array of CacheInterface witch the value is founded; get(string $methodName, array $params = [], array $attr = []); set(string $methodName, $data, $params = [], array $attr = []); clear(string $methodName, $params = [], array $attr = []); getLayer(string $cacheServiceName) : CacheAccessor; //return cache accessor for specific cache class (get RedisCache only for example) getCacheMap() : array; //return cache map schem for current object }
AdditionalCache
您可以通过 CacheManager 定义缓存,而无需类方法,并通过它进行操作
/** * @AdditionalCache( * "additionalCacheName", //virtual method name * layers = { //cache layers * @Cache(RedisCache::class, attribute={"ttl" = 86400}) //just @Cache annotation * } * ) */ class SomeClass { ....