ThinkPHP 8.0不内置自动识别URI或Header版本号的机制,但可通过路由分组(如->prefix('api/v1/'))支持路径版本,再配合自定义中间件提取Api-Version头并注入$request->param('version')实现双模式兼容,优先级为URI>Header,需避免路由冲突与生命周期绕过。

ThinkPHP 8.0 本身不内置“自动识别 URI 或 Header 中任一方式传入的版本号并统一路由”的机制,但可以通过组合路由配置、中间件和请求解析逻辑,实现 URI 路径版本 与 HTTP 请求头版本 的双支持——即客户端既可访问 /api/v1/user,也可发请求到 /api/user 并带上 Api-Version: v2,后端都能正确分发到对应版本逻辑。
URI 路径版本:按标准方式注册带前缀的路由组
这是 TP8 最原生、最稳定的支持方式。版本号作为 URL 路径一部分,由路由组件直接识别:
- 在
route/app.php中定义不同版本的路由组,使用prefix显式隔离 - 每个版本组内,用
version()方法声明支持的版本标识(仅作标记,不参与匹配) - 避免混用
prefix和version()做双重控制——version()在 TP8 中主要用于资源路由或模型绑定场景,路径匹配仍依赖prefix
示例:
// route/app.phpuse think\facade\Route;<br>
Route::group('api', function () {<br>
Route::get('user/:id', 'User/read')->name('api.v1.user.read');<br>
})->prefix('api/v1/');<br><br>
Route::group('api', function () {<br>
Route::get('user/:id', 'UserV2/read')->name('api.v2.user.read');<br>
Route::post('user', 'UserV2/create');<br>
})->prefix('api/v2/');
Header 版本支持:用中间件提取并注入路由参数
TP8 不提供开箱即用的 Header 版本路由,需手动将请求头中的版本信息转为可被路由识别的参数(如 version),再配合动态路由或控制器分发实现。
- 创建中间件(如
app/middleware/ApiVersionMiddleware.php),在请求进入时读取Api-Version或X-API-Version头 - 若头存在且合法(如
v1、v2),将其写入请求对象的变量:$request->version = $version;或更推荐地,用$request->withParam('version', $version) - 该中间件需注册在全局中间件列表中,且位置要早于路由解析中间件(确保路由能读到新增参数)
然后在通用路由中接收该参数:
Route::group('api', function () {<br>
Route::get('user/:id', 'User/versionedRead');<br>
})->prefix('api/');
控制器中根据 $request->param('version') 分支处理:
public function versionedRead(Request $request, $id)<br>
{<br>
$version = $request->param('version', 'v1');<br>
if ('v2' === $version) {<br>
return $this->v2Read($id);<br>
}<br>
return $this->v1Read($id);<br>
}
双模式兼容的关键细节
要让 URI 和 Header 两种方式真正共存、互不干扰,必须明确优先级和边界:
-
优先级建议:URI > Header —— 若 URL 已含
/v2/,则忽略 Header 中的版本;反之才启用 Header fallback。可在中间件中先检查$request->path()是否匹配/api/v\d+/,有则跳过 Header 解析 -
路由注册不能冲突 —— 不要同时为
/api/v1/user和/api/user绑定相同名称的路由,否则会触发重复注册警告或覆盖 -
响应头统一输出版本标识 —— 在基础控制器或响应中间件中追加
X-API-Version: v1,让客户端清楚当前实际执行的是哪个版本 -
错误处理需一致 —— 对非法版本(如
v3),无论来自 URI 还是 Header,都返回统一的400 Bad Request及提示,避免暴露内部结构
不推荐的“捷径”
有些方案试图用正则路由通配所有版本路径(如 /api/[v\d+]/user),或在全局 __call 中做版本转发,这类做法在 TP8 中容易绕过框架生命周期,导致中间件失效、日志丢失、异常捕获不全。应坚持路由分组 + 显式控制器分支的清晰结构,维护成本更低,调试也更直观。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











