Laravel包开发:在包内配置中间件组件的执行优先级
Laravel包内配置中间件执行优先级的方案
问题描述
我正在开发一款供5个以上应用使用的内部Laravel包,已在包的服务提供者中注册两个中间件组件:
public function boot() { /** @var Router $router */ $router = $this->app['router']; $router->pushMiddlewareToGroup('web', ComponentOne::class); $router->pushMiddlewareToGroup('web', ComponentTwo::class); $router->pushMiddlewareToGroup('api', ComponentOne::class); $router->pushMiddlewareToGroup('api', ComponentTwo::class); }
需要保证ComponentOne必须在ComponentTwo之前执行,目前仅能通过在每个使用该包的应用的Kernel类中配置$middlewarePriority实现:
protected $middlewarePriority = [ ComponentOne::class, ComponentTwo::class, ];
想知道是否可以直接在包内完成中间件优先级配置,避免每个应用手动修改。
解决方案
可以直接在包的服务提供者中配置中间件优先级,无需每个应用手动修改Kernel,具体实现如下:
在包的服务提供者boot方法中,添加优先级配置逻辑:
use Illuminate\Contracts\Http\Kernel; use Illuminate\Routing\Router; public function boot() { /** @var Router $router */ $router = $this->app['router']; $router->pushMiddlewareToGroup('web', ComponentOne::class); $router->pushMiddlewareToGroup('web', ComponentTwo::class); $router->pushMiddlewareToGroup('api', ComponentOne::class); $router->pushMiddlewareToGroup('api', ComponentTwo::class); // 配置中间件执行优先级 $kernel = $this->app->make(Kernel::class); // 移除已存在的中间件条目,避免重复 $kernel->middlewarePriority = array_filter( $kernel->middlewarePriority, fn($class) => $class !== ComponentOne::class && $class !== ComponentTwo::class ); // 确保ComponentOne优先级高于ComponentTwo array_unshift($kernel->middlewarePriority, ComponentOne::class); $kernel->middlewarePriority[] = ComponentTwo::class; }
逻辑说明
- 获取Kernel实例:通过Laravel容器获取
Illuminate\Contracts\Http\Kernel接口实例,而非依赖具体的App\Http\Kernel类,提升包的兼容性。 - 去重处理:先过滤掉优先级数组中已存在的两个中间件类,避免重复添加导致顺序混乱。
- 设置顺序:用
array_unshift将ComponentOne插入到优先级数组头部,保证它最先执行;再将ComponentTwo追加到数组中,确保它在ComponentOne之后执行。
这种方式的优势是所有集成该包的应用无需额外配置,包自身就能管控中间件的执行顺序,大幅降低集成成本。
内容的提问来源于stack exchange,提问作者chishiki
相关产品推荐
相关产品推荐

