根本原因是 symfony 3 默认启用 twig 磁盘缓存,即使 dev 环境 debug=true;必须在 twig.yaml 中显式配置 cache: false(布尔值,非字符串),并验证 var/cache/dev/twig 是否不再生成文件。

为什么改了 Twig 模板却没反应
根本原因不是缓存没清,而是 Symfony 3 的 twig.cache 配置默认仍启用磁盘缓存——哪怕 APP_ENV=dev 且 debug=true,Twig 依然会把编译结果写进 var/cache/dev/twig/ 下的 PHP 文件里。你保存了 base.html.twig,但请求加载的是已存在的 abc123.php,自然看不到变化。
-
debug=true只影响错误显示、Profiler、容器热加载,和 Twig 缓存开关无关 - Windows 下杀毒软件或 IDE “safe write” 可能导致文件修改时间(
filemtime())未更新,auto_reload判定失败 - 若
var/cache/dev/twig/目录不可写(权限/磁盘满/杀软拦截),Twig 会悄悄 fallback 到内存ArrayCache,行为像“部分生效”
必须显式设 cache: false 才算真正关闭
cache: false 是唯一可靠方式;写成 cache: null、cache: ~ 或留空,Symfony 都会回退到默认路径(如 %kernel.cache_dir%/twig),实际仍启用缓存。这个值必须是 YAML 的布尔字面量 false,不是字符串 "false"。
- 在
config/packages/twig.yaml中直接配置(优先级最高,覆盖环境判断):twig: cache: false
- 若项目用了多 Twig 实例(如邮件模板单独配了
email_twig),每个实例的配置都要加cache: false - 不要用
cache: "%kernel.cache_dir%/twig":该目录在cache:warmup后会被创建,等于变相开启缓存
验证是否真关掉了
别只信配置,要观察行为。关成功的表现是:删掉 var/cache/dev/twig/ 后,改模板、刷新页面,目录里**不再生成任何新 PHP 文件**。
- 执行
php bin/console debug:container --parameter=twig.options,检查输出中cache值是否为false(不是null、不是路径字符串) - 访问任意 Twig 渲染的页面(如
/_profiler),用curl -s -I http://localhost/_profiler | grep Last-Modified确认响应头含Last-Modified—— 这说明 Twig 正监听文件变更;若缺失,auto_reload很可能失效 - 改一个模板后,用
ls -la var/cache/dev/twig/看目录是否保持为空;若有文件出现,说明cache: false没生效或被其他配置覆盖
Docker / Windows 下容易被忽略的细节
本地开发用 Docker 或 Windows 时,缓存失效常卡在文件系统层,而非配置本身。
- Docker:确保
var/cache是可写卷,且宿主机与容器时区一致;否则filemtime()返回时间戳偏差,Twig 认为“文件没变” - PHPStorm 等 IDE 默认开启 “safe write”,保存时先写临时文件再原子替换,导致
inotify或轮询监听不到变更;需在 Settings → System Settings → Use "safe write" 中取消勾选 - Windows 上长路径(尤其嵌套深的
var/cache/dev/twig/...)可能触发 MAX_PATH 限制,报错file_put_contents(): Permission denied;可尝试用subst X: C:\your\project映射短路径解决
cache: false 写死在 twig.yaml,再加一条 CI 脚本断言,比每次问“你清缓存了吗”靠谱得多。











