Webman API 版本控制须用 Route::group(['prefix' => 'v1'], ...) 显式配置前缀,禁用字符串前缀;路径需带斜杠;控制器命名空间须严格匹配文件路径;reload 前须清 OPcache 与 autoloader 缓存;Header 版本解析需正则边界校验并存入 request attributes;逻辑复用应通过策略类而非继承。

Webman 里做 API 版本控制,别碰 Route::group() 的变量前缀或中间件跳转——它不支持 ThinkPHP 那套 Route::group('v1', ...) 语法,硬套会路由失效、类加载报错、reload 后还是旧逻辑。
Webman 路由分组不认字符串前缀,必须用完整路径
Webman 的 Route::group() 只接受数组配置,不支持 ThinkPHP 风格的单字符串前缀(如 'v1')。写成 Route::group('v1', [...]) 会直接忽略前缀,所有路由注册到根路径下。
- 正确写法是显式传
['prefix' => 'v1']:Route::group(['prefix' => 'v1'], function () { Route::get('/user', [App\Controller\V1\UserController::class, 'index']); }); - 路径必须带开头斜杠,
'/user'✅,'user'❌(否则匹配不到) - 控制器类名必须与文件路径严格一致:
app/controller/V1/UserController.php里必须是namespace app\controller\V1;,大小写敏感,Linux 下V1和v1是两个目录
改完路由 reload 没生效?先清 OPcache 和 autoloader 缓存
Webman reload 不会重载已由 Composer autoloader 加载过的类,也不会刷新 OPcache 中的 PHP 文件字节码——这是最常被忽略的「改了代码但没变」原因。
- 临时验证:执行
php -d opcache.enable_cli=0 start.php reload,排除 OPcache 干扰 - 长期方案:在
php.ini中设opcache.revalidate_freq=0(开发环境),或关掉opcache.enable - 检查
config/bootstrap.php或webman\support\Bootstrap是否提前require了控制器——这些代码只在 Worker 启动时执行一次,reload 不会重跑
Header 方式做版本控制更灵活,但得自己解析 Accept
Webman 没有 Laravel 的 Route::versioned() 或自动 Accept 解析,必须手动在中间件里提取并注入上下文。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
立即学习“PHP免费学习笔记(深入)”;
- Accept 值要带
vnd.前缀,例如application/vnd.myapp.v2+json,避免和标准 MIME 冲突 - 中间件里别用
strpos($accept, 'v2'),得用正则加边界:/v\d+(?![\d.]),否则v12会被误判为v1 - 解析后存到
$request->attributes->set('api_version', 'v2'),控制器里用$request->getAttribute('api_version')读取,别每个方法都重复 parse - 如果同时支持 Header 和
?version=v2,必须明确定义优先级(推荐 Accept > query),并在冲突时记录 warning 日志
版本间复用逻辑别靠继承,用策略类 + 显式调用
Webman 没有命名空间自动绑定机制,api/v1.User 这种字符串路由写法不存在。控制器必须显式声明,业务逻辑复用不能靠基类 initialize() 统一加载,否则 v1 请求也会初始化 v2 类。
- v1 和 v2 差异仅字段增减?用 Resource 层(如
app\resource\V1\UserResource/app\resource\V2\UserResource)组装响应,控制器保持干净 - v2 行为逻辑重构?建独立服务类:
app\service\V1\UserService和app\service\V2\UserService,都实现UserInterface,控制器里按$version动态 new 实例,但务必先class_exists($class)校验 - 禁止在控制器里写
if ($version === 'v2') { ... }—— 下次加 v3 就开始嵌套黑洞
真正卡住上线的不是路由怎么写,而是 reload 后类没重载、Accept 正则没边界、v2 服务类被 v1 请求提前加载——这些点不提前踩一遍,版本迭代就变成线上救火。


















