Webman中Accept头版本控制需自建中间件解析并存入请求属性,路由须统一注册于/api下,控制器按$version手动分发;因框架不原生支持Header路由匹配,且存在调试难、CDN干扰等问题,对外API推荐URL路径版本。

Webman 里用 Accept Header 做版本控制可行,但默认不生效——你得自己写中间件拦截、解析、路由分发,框架本身不内置该逻辑。
如何在 Webman 中提取 Accept Header 版本号
Webman 的 $request->header() 可以拿到原始 Header,但 Accept 值是类似 application/vnd.myapp.v2+json 这样的 MIME 类型字符串,不能直接当版本号用。
- 用
preg_match('/v(\d+)/', $request->header('Accept'), $matches)提取数字版本,$matches[1]就是v2中的2 - 注意大小写和空格:有些客户端发的是
accept小写,$request->header()默认不区分,但保险起见可统一转小写再匹配 - 没匹配到时必须 fallback,比如返回
406 Not Acceptable或走默认版本(如 v1)
Header 版本控制必须配中间件 + 路由前缀隔离
只靠中间件提取版本号没用,Webman 的路由系统不认识 Accept,它只按 URL 匹配。所以你得把版本信息“带进”路由上下文。
- 在中间件中解析出版本号后,存到请求属性:
$request->withAttribute('api_version', $version) - 所有 API 路由统一注册在
/api下(例如GET /api/users),不再写/v1/api/users这种路径 - 控制器里用
$request->getAttribute('api_version')拿版本,再手动分发逻辑,比如if ($version === '2') { return $this->handleV2($request); } - 别试图用
Route::group()做版本分组——Webman 的Group是路径前缀,对 Header 无效
为什么 Accept Header 方案在 Webman 里容易踩坑
它看起来标准,但实际落地时 Webman 缺少配套机制,导致隐性成本高。
立即学习“PHP免费学习笔记(深入)”;
- 浏览器地址栏直接访问
/api/users会失败:没有Accept头,中间件拿不到版本,多数人忘了加默认兜底 - Swagger/OpenAPI 文档难自动生成:
Accept是运行时行为,PHPDoc 注释没法描述不同 Header 对应不同响应结构 - CDN 和反向代理可能 strip 掉
Accept头,尤其当缓存策略开启时,v1 请求可能被缓存成 v2 响应 - 调试困难:
curl -H "Accept: application/vnd.myapp.v2+json" ...比改 URL 路径麻烦,前端联调时经常漏传
真正稳定的做法是:Header 版本只用于内部服务间调用(可控环境),对外暴露的 API 仍用 URL 路径版本(如 /api/v2/users),Webman 的路由和日志都认这个,不会绕弯子。



















