必须显式配置cache: false且auto_reload: true,因为debug=true仅控制profiler等特性,不关闭twig独立的磁盘缓存;cache: ~或null会被合并为默认路径,仍启用缓存。

关掉 Twig 模板缓存、让改完保存就生效,不是设 debug=true 就够了——必须显式写 cache: false,否则你改了 base.html.twig 刷新页面还是旧的。
为什么 debug=true 不等于模板不缓存
Symfony 的 debug 控制的是 Profiler、错误堆栈、容器热加载等,而 Twig 缓存由自身引擎独立管理。dev 环境下默认仍启用磁盘缓存(写入 var/cache/dev/twig/),目的是提升响应速度。它和 debug 开关无关,所以光开 debug 会给你“自动刷新”的错觉,实际只是缓存没被清干净或监听失效。
常见表现:
- 改完模板,刷新页面无变化
-
var/cache/dev/twig/下持续生成新 PHP 文件 - 删掉整个
twig/目录后首次请求变慢,但第二次又快了 → 说明缓存立刻重建了
怎么在 config/packages/twig.yaml 中正确关闭
必须用 YAML 字面量 false,不能是字符串 "false",也不能留空或注释掉。这个值会覆盖所有环境默认行为。
正确写法:
twig:
cache: false
auto_reload: true
关键点:
-
cache: false是唯一可靠方式;cache: ~或cache: null会被 Symfony 合并为默认路径(如%kernel.cache_dir%/twig),实际仍启用缓存 -
auto_reload: true必须显式保留(虽然 dev 默认开启),否则即使缓存关了,Twig 也不会检测文件修改时间,导致“改了也不重读” - 如果项目用了多个 Twig 实例(比如
email_twig),每个都要单独配cache: false
验证是否真关成功了
别只看配置写了没,得看运行时行为。
实操验证步骤:
- 手动删掉
var/cache/dev/twig/目录 - 改一个已加载的模板(比如加个
<!-- test -->)并保存 - 刷新页面,观察两点:
– 页面是否立即显示新增内容
–var/cache/dev/twig/下是否**没有新 PHP 文件生成** - 用
curl -I http://localhost/_profiler检查响应头是否含Last-Modified;若缺失,说明auto_reload失效或缓存仍在工作
Windows 用户额外注意:safe write(PHPStorm 默认开启)会导致文件替换不触发 inotify,建议关掉;Docker 环境要确认 var/cache 是可写卷,且宿主机与容器时区一致,否则 filemtime() 判断可能出错。
CI/CD 中必须断言的两个检查点
本地配对了不等于队友或流水线也生效。协作中真正麻烦的是:有人改了模板,自己看着正常,上线后发现 HTML 还是旧的——因为 CI 构建时用的是 prod 配置,或某台机器漏配了 cache: false。
CI 脚本里应加入:
-
php bin/console debug:container --parameter=twig.options | grep '"cache":.*false'—— 确保输出中cache字段值是布尔false,不是路径字符串或null -
curl -s http://app.test/_profiler | head -10 | grep -q "Last-Modified"—— 验证响应头存在,证明文件监听机制在线
把 cache: false 写死在 config_dev.yml 或 twig.yaml,再加这两条 CI 断言,比每次问“你清缓存了吗”靠谱得多。最常被忽略的,其实是 auto_reload: true 在某些 Docker Compose 场景下被覆盖,或者 APP_ENV 实际没生效却误以为在 dev 模式下运行。











