Symfony 6.4缓存组件分system和app两级池,system缓存框架内部数据(如路由、Twig模板),app供业务使用;开发建议用php_array适配器,生产推荐Redis并设default_lifetime。

Symfony 6.4 的缓存组件不是“开箱即用就自动加速一切”的黑盒,而是提供一套灵活、分层、可替换的缓存抽象和实现。它默认启用,但真正发挥作用,得理解它的两级结构(系统缓存 vs 应用缓存)、适配器选择逻辑,以及关键配置项如何影响开发与生产行为。
缓存的两个核心层级:system 和 app
Symfony 默认定义了两个主要缓存池:
-
cache.system:用于框架内部高频读取的数据,比如路由匹配结果、Twig 模板编译后的 PHP 类、Doctrine 元数据等。它默认使用
cache.adapter.filesystem,路径在var/cache/{env}/pools/system/ -
cache.app:供你自己的业务代码使用的通用缓存池,比如查数据库后缓存用户信息、API 响应等。它默认也走文件系统,但路径是
var/cache/{env}/pools/app/
这两个池彼此隔离,互不影响。修改 cache.app 的 TTL 不会改变 Twig 模板的重新编译行为,反之亦然。
快速上手:在控制器里用 cache.app
最常用方式是通过依赖注入获取 Psr\Cache\CacheItemPoolInterface 实例(它默认指向 cache.app):
- 在控制器方法参数中直接类型提示:
public function index(CacheItemPoolInterface $cache) - 写入缓存:
$item = $cache->getItem('user_123'); $item->set(['name' => '张三', 'role' => 'admin']); $item->expiresAfter(3600); $cache->save($item); - 读取缓存:
if ($cache->hasItem('user_123')) { $data = $cache->getItem('user_123')->get(); }
注意:getItem() 总是返回一个 CacheItemInterface 对象,即使键不存在——要靠 isHit() 或 hasItem() 判断是否命中。
开发环境必须知道的三个事实
- 缓存不会自动失效:改了控制器或 Twig 模板,
cache.app里的数据不会自动删,除非你设了expiresAfter()或手动调用$cache->deleteItem('key') -
cache:clear清的是整个var/cache/{env}目录,包括cache.system和cache.app,但不重置内存中的 opcache(尤其在 FrankenPHP worker 模式下需额外处理) - 开发时建议把
cache.app换成cache.adapter.php_array(内存缓存),避免磁盘 I/O 干扰调试:在config/packages/cache.yaml中加app: adapter: cache.adapter.php_array
生产环境推荐配置要点
- 不要用
filesystem作为cache.app的最终适配器:高并发下文件锁会导致性能下降。优先考虑cache.adapter.redis或cache.adapter.memcached - 确保 Redis/Memcached 服务可用,并在
.env中配置好连接串,如REDIS_URL=redis://127.0.0.1:6379 - 显式设置
default_lifetime防止意外永不过期:framework: cache: default_lifetime: 3600 - 如果用了 Symfony UX 或 Turbo,它们内部也依赖
cache.app,所以生产部署前务必验证该池能正常读写


















