twig.cache: false 是唯一可靠关闭方式;必须显式配置,否则 symfony 会回退至默认缓存路径,且需同步启用 auto_reload: true 并验证响应头含 last-modified 及缓存目录为空。

twig.cache: false 是唯一可靠关闭方式
仅设 APP_DEBUG=true 或 APP_ENV=dev 不会禁用 Twig 模板缓存,你改了 .twig 文件却没反应,大概率是缓存还在写入 var/cache/dev/twig/。必须在配置中显式声明 cache: false,否则 Symfony 会 fallback 到默认缓存路径(比如 %kernel.cache_dir%/twig),哪怕目录不存在也会尝试创建。
实操建议:
- 在
config/packages/twig.yaml中写死cache: false,不要留空、不要注释、不要设为null或字符串"false" - 若项目有多个 Twig 实例(如用于邮件的
email_twig),每个都要单独配cache: false - 删掉
var/cache/dev/twig/后刷新页面,该目录不应再生出新 PHP 文件;若有,说明配置未生效或被其他配置覆盖
auto_reload: true 必须启用,否则文件变更不被监听
cache: false 只让 Twig 每次重新解析模板,但若 auto_reload 关闭,它连“文件是否改过”都不检查,直接复用上次解析结果——你保存了模板,它根本不知道。
常见陷阱:
- Symfony 3 默认开启
auto_reload,但某些自定义环境(如测试环境或 Docker 内嵌配置)可能覆盖此值 - IDE 的“safe write”机制(先写临时文件再原子替换)会导致
filemtime()判断失准,Twig 认为文件没变;PHPStorm 中需关闭Settings > System Settings > Use "safe write" - Docker 容器内若宿主机与容器时区不同,
filemtime()返回时间可能滞后,缓存误判未更新
验证是否真关掉了:看响应头和缓存目录行为
别信“我改了,也刷新了”,得看证据。真正关掉后有两个可观察信号:
- 访问任意使用 Twig 渲染的页面,用
curl -I http://localhost/_profiler查响应头,应含Last-Modified字段(Twig 启用 auto_reload 时自动注入) -
var/cache/dev/twig/目录在请求后保持为空或只存在极少量固定文件(如error.html.php),绝不能出现按哈希命名的新*.php文件 - 执行
php bin/console debug:container --parameter=twig.options,输出中"cache" => false(注意是布尔false,不是null或字符串)
Windows 和 Docker 下最容易卡住的三个点
权限、路径、时钟这三样在非 Linux 环境下特别容易让缓存“看似关了实则没关”:
- Windows 上杀毒软件或 Windows Defender 可能锁定
var/cache/dev/twig/目录,导致file_put_contents()报Permission denied,Twig 回退到内存缓存(ArrayCache),表现像“部分生效” - Docker 中若
var/cache没挂成可写卷,或用了:ro挂载,Twig 无法清旧缓存也无法写新缓存,行为不可预测 - 容器与宿主机时区不一致时,
filemtime()返回的时间戳可能比文件实际修改时间早几秒,Twig 认为“还没变”,跳过重解析
最麻烦的不是配置写错,而是你本地关掉了,队友没关,CI 流水线也没校验——结果上线前大家看到的都是旧模板。把 cache: false 和 auto_reload: true 写死在版本控制里,并在 CI 中加一行 php bin/console debug:container --parameter=twig.options | grep '"cache" => false',比每次问“你清缓存了吗”有用得多。











