Webman中间件不支持process()方法传参,因框架强制要求实现MiddlewareInterface::process(Request $request, callable $next): Response接口;擅自添加参数会导致ArgumentCountError或中间件静默失效。

Webman 中间件本身不支持构造函数传参,也不能在 process() 方法里直接接收额外参数——这是框架洋葱模型决定的硬约束。想让中间件“带配置干活”,必须通过类属性 + 配置文件或路由绑定时传参来实现。
为什么不能在 process() 里加参数
Webman 要求所有中间件必须严格实现 MiddlewareInterface::process(Request $request, callable $next): Response 接口。如果你擅自改成 process(Request $request, callable $next, $config),框架调用时会抛出 ArgumentCountError 或静默跳过该中间件——因为 $next 是由框架内部注入的 callable,不是你可控的调用方。
常见错误现象包括:中间件代码写了但完全没执行、var_dump 没输出、日志无记录,且无任何报错提示。
根本原因在于 Webman 的中间件链是自动组装的,$next 的调用时机和参数列表由 Webman\Router 和 Webman\Http\Dispatcher 控制,外部不可干预。
正确传参方式:用类属性 + 配置文件
把配置项抽到 config/plugin/xxx/app.php 或 config/middleware.php,在中间件类中通过静态属性或构造函数读取(注意:构造函数仅用于初始化,不能依赖请求上下文)。
- 在
config/plugin/my-validator/app.php中定义:return [ 'rules' => [ 'username' => 'required|alpha_dash|min:3', 'email' => 'required|email', ], 'message' => '参数校验失败' ]; - 中间件类中用
config('my-validator.rules')获取配置,而不是硬编码 - 避免在
process()内做耗时初始化(如 new Validator),应提前在__construct()或静态方法中完成 - 若需不同路由用不同规则,不要靠一个中间件扛全部,改用路由级中间件绑定 + 不同类实例
路由绑定时传参:用闭包包装中间件
Webman 原生不支持 ->middleware(CheckRole::class, ['admin']) 这种写法,但你可以用匿名函数绕过限制:
在 config/route.php 中这样写:
Route::get('/admin/users', [app\controller\AdminController::class, 'index'])
->middleware(function ($request, $next) {
return (new app\middleware\CheckRole(['admin']))->process($request, $next);
});
对应中间件需支持构造传参:
class CheckRole implements MiddlewareInterface
{
protected array $roles;
<pre class="brush:php;toolbar:false;">public function __construct(array $roles)
{
$this->roles = $roles;
}
public function process(Request $request, callable $next): Response
{
$userRole = $request->header('X-Role', 'guest');
if (!in_array($userRole, $this->roles)) {
return response('Forbidden', 403);
}
return $next($request);
}}
⚠️ 注意:这种方式每次请求都会 new 一次中间件实例,不适合带 heavy 初始化逻辑的类;高频路径建议改用配置驱动。
全局中间件如何区分不同分组配置
看 config/middleware.php 的结构就知道,Webman 支持按「应用前缀」分组注册中间件:
return [
// 全局中间件(所有请求都走)
'' => [
app\middleware\TrustProxies::class,
],
// api 应用专属中间件(只匹配 /api/* 路由)
'api' => [
app\middleware\ValidateMiddleware::class,
app\middleware\RateLimit::class,
],
// admin 应用专属中间件
'admin' => [
app\middleware\AuthMiddleware::class,
],
];
这时你可以在中间件内部用 $request->path() 或 $request->method() 做轻量判断,但更推荐的是——为不同分组写不同中间件类,职责清晰、便于测试和复用。
容易被忽略的一点是:config/middleware.php 中的键名(如 'api')必须与你的应用目录名或路由前缀严格一致,否则分组不生效;而且这个分组机制只对 config/route.php 中未显式指定 middleware 的路由起作用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











