Laravel 中间件优先级由 $middlewarePriority 数组控制,而非路由声明顺序;需将自定义中间件(如 \App\Http\Middleware\Website::class)按依赖关系插入该数组,修改后执行 php artisan config:clear。

在 Laravel 中,并没有名为 priority() 的方法可以直接调用(比如 middleware('auth')->priority(10) 这类写法是无效的)。所谓“用 priority 排中间件优先级”,实际是指通过框架内置的 $middlewarePriority 机制,显式声明中间件类的执行顺序,从而影响它们在整个请求生命周期中的调用先后。
核心:靠 $middlewarePriority 数组控制顺序
Laravel 不按你在路由里写的中间件数组顺序执行(如 ->middleware(['website', 'auth'])),而是会将部分中间件(尤其是涉及 session、auth、csrf 等有状态中间件)按 $middlewarePriority 数组里的位置重新排序。你的自定义中间件必须被放进这个数组,且排在依赖它的中间件之前,才能真正“优先”运行。
- 打开
app/Http/Kernel.php - 找到
protected $middlewarePriority = [...]属性(Laravel 9+ 默认存在) - 把你希望提前执行的中间件类(如
\App\Http\Middleware\Website::class)加到数组开头或 auth 类之前
为什么不能只靠路由里写顺序?
因为 Laravel 内核会对某些中间件做“自动归位”。例如 Authenticate 和 StartSession 属于高优先级中间件,即使你写成 ['website', 'auth'],内核仍可能先初始化 session、再跑 auth,最后才进你的 website 中间件——导致子域名校验失效,用户被错误跳转到登录页而不是 404。
- 路由中声明的顺序仅作参考,不具强制力
- 真正起决定作用的是
$middlewarePriority中的类名位置 - 未列入该数组的中间件,会被放在默认队列末尾执行
实操要点
确保你的中间件能被正确识别和排序:
- 使用完整命名空间,例如
\App\Http\Middleware\Website::class,不能只写Website::class - 若中间件依赖 session(比如要读取用户信息),它必须放在
StartSession之后;但若只是做子域名存在性检查(不依赖 session),就应放在它之前 - 修改后需清空配置缓存:
php artisan config:clear(虽然 kernel 不走 config 缓存,但保险起见建议执行) - 可通过日志或
dd()在各中间件 handle 方法中验证执行顺序
不是所有中间件都需要进 $middlewarePriority
只有那些需要与 auth/session/csrf 等内置中间件“抢顺序”的自定义中间件才需加入。普通日志、权限校验、API 格式处理等中间件,通常放在 $middleware 或 $routeMiddleware 中,按数组顺序执行即可,无需干预优先级数组。











