danieldoader / cache-bundle
基于注解的缓存,用于 Symfony 容器内的服务
Requires
- php: >=7.0
- doctrine/annotations: ~1.3
- ocramius/proxy-manager: 2.*
- psr/cache: 1.0.*
- psr/container: ^1.0
- psr/log: 1.*
- symfony/dependency-injection: >3.3
Requires (Dev)
- phing/phing: @stable
- phpmd/phpmd: @stable
- phpunit/phpunit: 5.*
- satooshi/php-coveralls: ~1.0
- sebastian/phpcpd: ~2
- squizlabs/php_codesniffer: 2.*
- symfony/cache: 3.*
- symfony/framework-bundle: @stable
- symfony/http-kernel: 3.*
- symfony/monolog-bundle: @stable
Suggests
- symfony/cache: 3.*
- dev-master
- 4.1.1
- 4.1.0
- 4.0.1
- 4.0.0
- v3.x-dev
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.0.1
- 2.0.0
- v1.x-dev
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-sfv5
- dev-update_namespace_and_package_versions
- dev-add_own_filewriter_to_avoid_ocramius_permission_bug_from_2.1_and_up
- dev-add_own_filewriter_to_avoid_ocramius_permission_bug_from_2.1_and_up_branch
- dev-low
This package is auto-updated.
Last update: 2024-08-29 04:03:46 UTC
README
基于注解的缓存,用于 Symfony 容器内方法响应。
这个组件可以帮助您通过简单的注解或属性来添加缓存。您可以将缓存存储在任何实现了 PSR-6:缓存接口的类中,无论是简单的数组还是 redis/memcache 存储。
工作原理
这个组件将扫描所有定义的服务中的方法,寻找 Cache 注解或属性(PHP 8 及以上版本)。
对于找到 Cache 注解/属性的 所有服务,它将创建一个代理类(使用 ocramius/proxy-manager),该类扩展了服务类,包含 CacheableClassTrait 并覆盖了带有 Cache 注解/属性的 方法。
覆盖的方法包括对 getCached
方法的调用,该方法识别注解细节,获取键,获取 Cache PSR-6 实现并从缓存中获取结果。如果未找到具有生成的缓存键的数据,它将调用原始方法,然后将响应保存到指定的提供者。
该组件有一个 CompilerPass 实现将搜索并覆盖服务定义,使用上述过程中创建的代理类。
安装
使用 Symfony Flex
使用 Symfony Flex 是安装和配置 AnnotationCacheBundle 的最简单方法
composer require symfony/flex ^1.0
composer config extra.symfony.allow-contrib true
composer require emag-tech-labs/annotation-cache-bundle
Symfony Flex 将自动注册和配置该组件。
不使用 Symfony Flex
如果您的应用程序不使用 Symfony Flex,您可以按照以下步骤手动配置该组件
步骤 1:下载组件
打开命令行,进入您的项目目录,执行以下命令以下载此组件的最新稳定版本
composer require emag-tech-labs/annotation-cache-bundle
步骤 2:启用组件
然后,通过将其添加到项目 config/bundles.php
文件中注册的组件列表中,启用该组件
// config/bundles.php return [ // ... EmagTechLabs\AnnotationCacheBundle\AnnotationCacheBundle::class => ['all' => true], ];
步骤 3:配置
最简单的方法是将配置导出到 configs/packages/emag_annotation_cache.yaml
。
bin/console config:dump-reference AnnotationCacheBundle
配置示例
您必须配置 PSR6 兼容的服务的名称,这意味着它必须实现 Psr\Cache\CacheItemPoolInterface
# app/config/services.yaml services: cache.array: class: Symfony\Component\Cache\Adapter\ArrayAdapter cache.redis: class: Symfony\Component\Cache\Adapter\RedisAdapter arguments: ['@predis']
#configs/packages/emag_annotation_cache.yaml # Annotation Cache Bundle annotation_cache: provider: default: cache.redis array: cache.array ignore_namespaces: - 'Symfony\\' - 'Doctrine\\'
用法
为要缓存的 方法添加 Cache
注解。
注解参数
cache
- 缓存前缀,字符串,默认值:null(例如:'my_custom_prefix_')key
- 要包含在缓存键哈希生成中的参数(s)名称,字符串,arg 名称由逗号分隔,默认值:''(例如:'a,b')ttl
- 缓存存储的时间(秒),整数,默认值:600(例如:'3600')reset
- 是否应重置缓存,布尔值,默认值:false(例如:'true')storage
- 如果定义了多个提供者,可以指定要使用的提供者,字符串,默认值:'default'(例如:'array')
使用 Doctrine Annotations 库定义的注解
use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache; /** * @Cache(cache="<put your prefix>", [key="<name of argument to include in cache key separated by comma>", [ttl=600, [reset=true, [storage=default ]]]]) */
示例
namespace AppCacheBundle\Service; use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache; class AppService { /** * @Cache(cache="app_high_cpu", ttl=60) * * @return int */ public function getHighCPUOperation(): int { sleep(10); // 'Simulate a time consuming operation'; return 20; } }
使用 PHP 8 属性定义的注解
use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache; #[Cache(cache:'<put your prefix>', key:'<name of argument to include in cache key separated by comma>', ttl:600, reset: true, storage: 'default')]
示例
namespace AppCacheBundle\Service; use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache; class AppService { #[Cache(cache:'app_high_cpu', ttl: 60)] public function getHighCPUOperation(): int { sleep(10); // 'Simulate a time consuming operation'; return 20; } }
使用场景
以下您可以找到两种使用此组件的方法
配置
# app/config/services.yaml services: cache.array: class: Symfony\Component\Cache\Adapter\ArrayAdapter cache.redis: class: Symfony\Component\Cache\Adapter\RedisAdapter arguments: ['@predis']
#configs/packages/emag_annotation_cache.yaml # Annotation Cache Bundle annotation_cache: provider: default: cache.array redis: cache.redis ignore_namespaces: - 'Symfony\\'
服务代码
此组件可以以多种方式使用,以下展示了两种方式。
第一种情况是最常见的一种,其中你有一个执行多个耗时操作的方法,并且你想要将响应缓存到Redis中,带有一个前缀(simple_time_consuming_operation_),在指定的时间(以下示例中为60秒)内。这里的逻辑是先在Redis中查找值,如果没有找到,则运行实际的方法,获取结果并将其缓存以供后续使用,同时考虑到在@Cache
注解中传递的参数。
第二种情况可以用来生成缓存并在命令中预热,或者在特定事件触发时更新缓存,或者更新数据库中的信息。根据以下示例,你可以设置一个cron,每3000秒运行一次,这将再生缓存,使其在过期之前可用。因为我们使用了相同的缓存前缀和键,当两个方法(getTimeConsumingOperationValueWithReset
和getTimeConsumingOperationValue
)传递相同的参数值时,生成的缓存键将是相同的,在本例中为:time_consuming_operation_7fe49b314fb356bee76dbd3b8716b4d5ab5db600。这意味着两个方法将写入(和读取)同一个缓存键。因为第二个方法将reset
参数设置为true,所以对第二个方法的任何调用都将用函数的新结果覆盖键time_consuming_operation_7fe49b314fb356bee76dbd3b8716b4d5ab5db600中的缓存值。
namespace AppCacheBundle\Service; use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache; class AppService { /** * @Cache(cache="simple_time_consuming_operation_", ttl=60, storage="redis") * * @param int $a * @param int $b * * @return int */ public function getSimpleTimeConsumingOperationValue(int $a, int $b): int { sleep(10); // 'Simulate a time consuming operation'; return $a + $b; } #[Cache(cache:'time_consuming_operation_', key: 'a,b', ttl: 3600, storage: 'redis')] public function getTimeConsumingOperationValue(int $a, int $b): int { return $this->getTimeConsumingOperationValueWithReset($a, $b); } #[Cache(cache:'time_consuming_operation_', key: 'a,b', ttl: 3600, reset: true, storage: 'redis')] public function getTimeConsumingOperationValueWithReset(int $a, int $b): int { sleep(10); // 'Simulate a time consuming operation'; return $a + $b; } }
服务调用
// from controller /** AppService $appService */ $appService->getTimeConsumingOperationValue(1, 2); // from command /** AppService $appService */ $appService->getTimeConsumingOperationValueWithReset(1, 2);
贡献
感谢您对贡献的兴趣!有很多方式可以为这个项目做出贡献。从这里开始这里。