Laravel - 仅针对特定路线初始化 class

Laravel - Initialize class only for specific routes

在我的应用程序中,我有一组路由在发送之前需要一些引导。

说明情况:

有一个前缀为 'app' 的特殊路由组。所有这些路线也有一些参数:

site.dev/app/index?age=11&else=af3fs4ta21

如果没有这些参数,则不应允许用户访问路由。我通过创建一个简单的路由中间件来完成它。

if (!$request->exists('age') || !$request->exists('else')) {
        return redirect('/');
}

下一步是初始化一个class,它将路由参数作为构造参数。然后 param "else" 被用作 db 调用的参数。我需要在 /app 路由组的每条路由中访问这个 class。

为了实现我尝试设置服务提供商:

public function register()
{
    $this->app->singleton(Dual::class, function ($app) {
        return new Dual($this->app->request->all());
    });
}

然后我创建了一个扩展 BaseController 并将 Dual class 传递给其构造函数的特殊控制器。

class DualController extends Controller
{
    public function __construct(Request $request, Dual $dual)
    {
        $this->middleware(\App\Http\Middleware\DualMiddleware::class);

        $this->dual = $dual;
    }
}

然后每个控制器都扩展 DualController 并通过 $this->dual->method() 访问 Dual class。

如果路由参数就位并且数据库中已经有一行,它就可以工作。

问题

此中间件在 ServiceProvider 和 DualController 初始化后执行 class Dual。所以,中间件并没有真正起作用。如果路由参数不存在,它将失败。

此外,如果由于某种原因数据库中没有所需的行,Dual class 将不会被初始化(因为它取决于对数据库的调用)并且整个应用程序将崩溃,说我正在尝试对 null 执行操作。

期望的行为

首先检查路由是否存在参数。

其次,检查数据库中是否有包含路由键的行。

第三 - 尝试初始化 Dual class 并将其传递给路由组 /app 使用的所有控制器。

如果任何步骤失败 -> 显示正确的消息。

双class的一部分:

class Dual
{
    protected $client = null;
    public $config = [];

    public function __construct($config)
    {
        $this->config = $config;
        $this->bootstrap();
    }

    public function getEli()
    {
        $eli = Eli::where(['else' => $this->config['else']])->first();
        return $eli;
    }

    public function instantiateClient()
    {
        $client = Client::factory(Client::ADAPTER_OAUTH, [
            'entrypoint' => $this->getEli()->eli_url,
            'client_id' => '111',
            'client_secret' => '111',
        ]);

        $client->setAccessToken($this->getEli()->accessToken()->first()->access_token);

        return $client;
    }

    public function getClient()
    {
        if ($this->client === null)
        {
            throw new \Exception('Client is NOT instantiated');
        }

        return $this->client;
    }

    public function bootstrap()
    {
        $this->client = $this->instantiateClient();
    }

您可以在中间件中执行此操作:

$isElseExists = Model::where('else', request('else'))->first();
if (request('age') && request('else') && $isElseExists) {
    return $next($request);
} else {
    return back()->with('error', 'You are not allowed');
}

如果一切正常,将执行控制器方法。然后你就可以注入 Dual class 而无需任何额外的逻辑。

如果出现问题,用户将被重定向到之前的 URI,并在会话中闪现错误消息。