中间件必须接收 $request 和 $next 两个参数,$next 是后续链的 callable 引用,不调用则流程中断;$request 是 webman\http\request 实例,支持 get()、header() 等方法,返回值必须是 response 实例。

中间件必须接收 $request 和 $next 两个参数
Webman 的中间件不是“插上就能用”的黑盒,它依赖明确的函数签名来维持洋葱模型。如果你写的中间件 process() 方法只接收 $request,或者漏掉 $next,框架会直接报错或静默跳过——因为没有 $next 就无法把请求往下传。
常见错误现象包括:路由完全不触发、控制器方法没执行、日志里看不到中间件输出,但又没报错。
-
$request是Webman\Http\Request实例,可直接调用$request->get()、$request->header()等方法 -
$next是一个 callable,代表后续中间件链或最终控制器;必须显式调用$next($request)才能继续流程 - 若想拦截请求(比如未登录),直接
return response(..., 401),**不要**调用$next - 返回值必须是
Webman\Http\Response实例,不能是字符串、数组或json()调用结果(除非你确认它已封装为 Response)
如何在路由中绑定鉴权中间件(非全局)
全局中间件容易误伤静态资源或开放接口,实际项目中更推荐按需绑定。Webman 不支持 Laravel 那种 ->middleware('auth') 链式写法,而是靠路由配置数组的 middleware 键。
使用场景:仅对 /api/user、/admin/* 这类敏感路径启用鉴权,而 /public/* 或 /health 保持免鉴权。
- 在
config/route.php中定义路由时,加'middleware' => [app\middleware\AuthMiddleware::class] - 支持数组形式叠加多个中间件:
'middleware' => [app\middleware\CheckToken::class, app\middleware\CheckPermission::class] - 注意:中间件类名必须是完整命名空间,且文件路径与 PSR-4 规则一致(如
app/middleware/AuthMiddleware.php) - 如果中间件未生效,先检查
config/bootstrap.php是否已加载config/route.php,再确认类文件是否存在、命名是否拼错
AuthMiddleware 中如何安全读取用户身份并传递给控制器
鉴权中间件不该只做“放行/拦截”二选一,还要把验证后的用户信息透传下去。Webman 不提供类似 Laravel 的 $request->user() 原生方法,得自己挂载。
典型做法是用 $request->withAttribute() 把用户数据存入请求对象,后续控制器或中间件可通过 $request->getAttribute('user') 获取。
- 不要往
$_SESSION或全局变量塞数据,协程环境下会串用户 - 示例逻辑:从 header 取 token → 解析出 user_id → 查询数据库 →
$request = $request->withAttribute('user', $userInfo)→return $next($request) - 控制器中获取:
public function index(Request $request) { $user = $request->getAttribute('user'); } - 如果控制器没声明
Request参数类型,改用助手函数:$user = request()->getAttribute('user'); - 务必校验
getAttribute()返回值是否为null,避免未鉴权请求意外走到业务逻辑里
静态资源路径被鉴权中间件误拦怎么办
Webman 默认的 StaticFile 中间件和自定义鉴权中间件共存时,容易出现“访问 /static/js/app.js 返回 401”的问题——这是因为路由匹配优先级或中间件注册顺序不对,导致静态文件请求也进了鉴权流程。
根本原因不是鉴权逻辑写错了,而是中间件作用范围没收敛。
- 检查
config/static.php中'enable' => true是否开启,且StaticFile::class在middleware数组中位置靠前(应早于鉴权中间件) - 更稳妥的做法:在鉴权中间件开头加路径白名单判断:
if (preg_match('/^\/(static|uploads|favicon\.ico)/', $request->path())) { return $next($request); } - 避免用
strpos($request->path(), '/static') === 0,因为 PHP 的===对 false 和 0 判断易出错,正则更可靠 - 开发期可用
var_dump($request->path())确认真实路径,注意 Webman 默认会自动去除重复斜杠和解析..
中间件真正的复杂点不在写法,而在责任边界:哪个中间件该处理什么、谁先谁后、怎么避免副作用泄漏。尤其在协程模型下,共享状态(如全局变量、静态属性)比传统 PHP-FPM 更危险。别图省事把权限校验、日志、缓存全塞进一个中间件里——拆开,各自专注一件事。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











