必须在 Twig 配置中显式设置 cache: false 并确保 auto_reload: true,才能真正禁用模板缓存;仅设 debug=true 无效,且错误写法(如 cache: ~)仍会启用默认缓存。

为什么 debug=true 不能关掉 Twig 模板缓存
Symfony 的 debug=true 控制的是错误显示、Profiler、容器热加载等行为,和 Twig 自身的模板编译缓存无关。Twig 默认在 dev 环境下仍会把 .twig 文件编译成 PHP 并写入 var/cache/dev/twig/,你改了模板却没反应,八成是这个目录里还躺着旧的 abc123.php。
常见错误现象包括:保存模板后刷新页面无变化、cache:clear 后又马上生成新缓存文件、IDE(如 PHPStorm)提示“文件已修改但未重载”。
-
debug=true不等于twig.cache=false,这是两个独立开关 - Twig 缓存路径默认为
%kernel.cache_dir%/twig,即使目录为空,它也会重新创建并写入 - Windows 下杀毒软件或文件锁可能导致
file_put_contents(): Permission denied,表现为缓存不更新但也不报错
必须设 cache: false 而不是注释或留空
在 config/packages/twig.yaml(或 Symfony 3 的 app/config/config_dev.yml)中,cache 配置项不是布尔值,而是一个路径;但 YAML 的 false 字面量是唯一能真正禁用它的写法。
错误写法示例:cache: ~、cache: null、cache: ""、# cache: /tmp —— 这些都会被 Symfony 合并回默认路径,缓存照常工作。
- 正确写法只有:
cache: false - 如果用了多个 Twig 实例(比如邮件模板单独配了
email_twig),每个都要单独加这一行 - 设成
false后,Twig 会跳过写入编译文件逻辑,每次请求都重新解析原始.twig
验证是否真关掉了缓存
别信“我改了配置就生效”,得看 var/cache/dev/twig/ 目录有没有动静。删掉它,改一个模板,刷新页面——如果目录没新建任何 PHP 文件,说明关成功了。
容易被忽略的干扰点:
- 某些 IDE 开启了“safe write”,保存时先写临时文件再原子替换,Twig 的
filemtime()检测不到变更 → 关掉 IDE 的 safe write - Docker 环境中,
var/cache卷若挂载为只读,或宿主机与容器时区不一致,会导致缓存判断失效 - 用
php bin/console server:run启动时没加--env=dev,实际跑在 prod 模式下,cache: false配置根本没加载
auto_reload: true 是前提,不是可选项
cache: false 只解决“不写缓存”,但要让修改实时生效,还得靠 auto_reload: true —— 它控制 Twig 是否每次请求都检查模板文件的修改时间。Symfony 3 默认开启,但如果你在配置里显式覆盖了 twig.options,可能意外把它关掉了。
检查方式:运行 php bin/console debug:container --parameter=twig.options,输出中必须有 "auto_reload": true 和 "cache": false 两项同时存在。
- 如果只看到
"cache": false但auto_reload是false或缺失,模板仍不会自动更新 - CI 流水线里建议加断言:
grep -q '"auto_reload":true' - 关掉缓存后性能会下降(每次解析 .twig),这是调试阶段必须接受的代价,不是配置错了
真正麻烦的不是找不到开关,而是改完模板后,你本地生效了,队友那边还在读 var/cache/dev/twig/xxx.php 里的旧代码。把 cache: false 和 auto_reload: true 写死在开发配置里,并在 CI 中验证这两项值,比每次问“你清缓存了吗”靠谱得多。


















