必须显式配置 cache: false 且 auto_reload: true 才能禁用 twig 模板缓存,app_debug=true 不影响 twig 编译缓存,需通过 debug:config 验证并配合 ci 断言确保生效。

关不掉 Twig 模板缓存,不是因为你没清缓存,而是 debug=true 根本不等于“不缓存”——Symfony 3 默认即使在 dev 环境下,Twig 仍会把 .twig 编译成 PHP 文件写入 var/cache/dev/twig/,改完模板不生效,90% 是这个缓存还在干活。
必须显式设 cache: false,不能只靠 APP_DEBUG=true
Twig 的缓存开关和 Symfony 的 debug 模式是两套逻辑。设 APP_DEBUG=true 只影响异常显示、Profiler、容器热更新等,**不影响 Twig 是否写编译文件**。
-
cache: false是 YAML 字面量(不是字符串"false"),必须写死在配置里 - 不要留空:
cache: ~或cache:(无值)会被 Twig 当作“用默认路径”,实际仍启用缓存 - 不要用变量路径:
cache: "%kernel.cache_dir%/twig"—— 这个目录只要存在且可写,缓存就生效 - 验证方式:改一个
.twig文件后,ls -l var/cache/dev/twig/应该为空或完全不生成新文件
auto_reload: true 得开着,否则关了缓存也检测不到改动
禁用缓存后,Twig 不再依赖编译文件,但要实时读取原始 .twig 并解析,就得靠 auto_reload 去比对文件修改时间。它默认是 true,但如果你在配置里覆盖过 Twig 选项,可能被关掉。
- 检查
config/packages/twig.yaml或app/config/config_dev.yml中是否含auto_reload: false - 运行
php bin/console debug:config twig,确认输出中auto_reload是true - 如果关了
auto_reload,即使cache: false,Twig 也会把模板内容“记在内存里”,改完保存也不刷新
Windows 下特别容易卡在权限和路径上
Windows 对 var/cache/dev/twig/ 目录的写入限制比 Linux 严得多,尤其当杀毒软件、OneDrive 或 WSL 跨区挂载介入时,file_put_contents() 报 Permission denied 不一定代表你配错了,可能是目录被锁死。
- 先手动删掉整个
var/cache/dev/twig/目录,再试一次请求,看是否重建失败 - 用
icacls var\cache /grant Users:F /t(管理员权限)确保当前用户有完全控制权 - 避免路径含中文、空格或超长名(Twig 生成的哈希文件名可能很长,NTFS 有 260 字符限制)
- 如果用 Docker,确认
var/cache是 volume 映射且权限一致,别让容器内 UID 和宿主机不匹配
CI/CD 里得断言 twig.options.cache === false
本地关掉了,不等于队友或流水线也关了。协作项目里最麻烦的是“我这儿好使,你那儿不行”。不能靠口头约定,得用机器验证。
- CI 脚本里加一行:
php bin/console debug:container --parameter=twig.options | grep '"cache":.*false' - 再加一个轻量 HTTP 检查:
curl -sI http://app.test/_profiler | grep -i "Last-Modified"—— 有这个 header 才说明auto_reload在工作 - 别信
APP_ENV=dev就万事大吉:Docker Compose、IDE 内置服务器、甚至php -S都可能绕过环境变量,导致实际跑在 prod 模式下
真正难的不是找到那行 cache: false,而是确保它在所有机器上都起效、且没人能意外覆盖它。写死配置 + CI 断言,比每次问“你清缓存了吗”省三小时排查时间。











