Heim > Fragen und Antworten > Hauptteil
Standardmäßig stellt Laravel zwei Middlewares zur Ratenbegrenzung (Drosselung) bereit:
\Illuminate\Routing\Middleware\ThrottleRequests::class \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class
Wie in der Dokumentation angegeben, können Sie die Zuordnung in Kernel.php
wie folgt ändern, wenn Sie Redis als Cache-Treiber verwenden:
/** * 应用程序的中间件别名。 * * 别名可用于将中间件方便地分配给路由和组,而不是使用类名。 * * @var array<string, class-string|string> */ protected $middlewareAliases = [ // ... 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class // ... ];
Das Problem besteht darin, dass das oben Genannte nicht dynamisch, sondern umgebungsabhängig ist. In meiner staging
和production
环境中,我使用Redis,但在我的local
和development
Umgebung verwende ich beispielsweise kein Redis.
Es gibt eine offensichtlich schmutzige Lösung, etwa diese (Kernel.php
):
/** * 应用程序的中间件别名。 * * 别名可用于将中间件方便地分配给路由和组,而不是使用类名。 * * @var array<string, class-string|string> */ protected $middlewareAliases = [ // ... 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class // ... ]; /** * 创建一个新的HTTP内核实例。 * * @param \Illuminate\Contracts\Foundation\Application $app * @param \Illuminate\Routing\Router $router * @return void */ public function __construct(Application $app, Router $router) { if ($app->environment('production')) { $this->middlewareAliases['throttle'] = \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class; } parent::__construct($app, $router); }
Gibt es eine „Standard“-Methode, um relevante Middleware dynamisch auszuwählen, ohne sie zu überschreiben Kernel
构造函数的情况下实现这一点?基本上,我希望我的应用程序可以根据环境是否设置为production
(或者默认缓存存储设置为redis
).
Die obige Lösung funktioniert nicht, da auf den Kernel zugegriffen wird, bevor die Anwendung gestartet wird, sodass die Umgebung derzeit nicht verfügbar ist. Eine andere Lösung, die ich derzeit in Betracht ziehe, besteht darin, die Basisklasse ThrottleRequests
so zu erweitern, dass die relevanten Klassen dynamisch aufgerufen werden können.
P粉0434322102024-01-11 16:27:49
经过大量的研究和测试,我得出的结论是在RouteServiceProvider
中动态设置throttle
中间件是最好的解决方案,代码如下:
class RouteServiceProvider extends ServiceProvider { /** * 启动任何应用程序服务。 * * @return void */ public function boot(): void { $this->registerThrottleMiddleware(); } /** * 注册用于限制请求的中间件。 * * @return void */ private function registerThrottleMiddleware(): void { $router = app()->make('router'); $middleware = config('cache.default') !== 'redis' ? \Illuminate\Routing\Middleware\ThrottleRequests::class : \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class; $router->aliasMiddleware('throttle', $middleware); } }