frankenphp 不自动感知 symfony 的 asset version 变更,因其不读取 framework.assets.version 配置,仅按路径转发且默认忽略 ?v= 参数;需通过文件名哈希或显式配置 vary_by_query 实现缓存联动。

FrankenPHP 的静态资源缓存不会自动感知 Symfony 的 asset version 变更,必须手动触发或配置联动机制。
FrankenPHP 不读取 Symfony 的 assets.version 配置
FrankenPHP 自身不解析 Symfony 的 framework.assets.version 或 assets.base_urls,它只按 HTTP 请求路径原样转发或缓存文件。即使你在 config/packages/framework.yaml 里设置了:
framework:
assets:
version: 'v2.1'
生成的 URL 如 /build/app.css?v=v2.1 对 FrankenPHP 来说只是个普通路径 —— 它不会因为 version 字符串变化就自动失效旧缓存。
- FrankenPHP 默认对
.css、.js等扩展名启用强缓存(Cache-Control: public, max-age=31536000) - 它依据的是文件最后修改时间(
mtime)或 ETag,而非查询参数内容 -
?v=v2.1这类参数在默认配置下被忽略,不参与缓存键计算
让 FrankenPHP 正确响应资源版本变更的两种方式
核心思路:要么让缓存键包含 version 信息,要么让文件内容变更触发 mtime 更新。
- 用
assets.packages配合json_manifest_path,把 version 嵌入文件名本身(如app.a1b2c3.css),FrankenPHP 会自然识别为新资源 - 在构建流程中执行
touch public/build/app.css,强制更新文件 mtime,FrankenPHP 的 ETag 会随之变化 - 若必须保留
?v=xxx形式,需在 FrankenPHP 的frankenphp.yaml中显式启用 query string 缓存区分:static_files: cache: vary_by_query: ["v"]但注意:这会增加缓存碎片,不推荐用于高频变动的 version 值
常见失效失败场景和验证方法
缓存没刷新,大概率是以下某个环节断了链:
- Symfony 模板里仍用
{{ asset('build/app.css') }}而非{{ asset('build/app.css', 'versioned') }},导致根本没加 version 参数 - FrankenPHP 的
public/目录挂载为只读卷(如 Docker 中),touch失败且无报错 - 浏览器本地缓存覆盖了 FrankenPHP 缓存,用
curl -I https://yoursite.com/build/app.css直接查响应头,看ETag或Last-Modified是否已更新 - CDN(如 Cloudflare)在 FrankenPHP 前多加了一层缓存,且未配置忽略
v=参数
最稳妥的做法是放弃 query 参数式 version,改用文件名哈希 —— 这绕过了所有中间层对 URL 参数的处理差异,FrankenPHP、CDN、浏览器全都能一致识别变更。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











