在 Laravel 服务提供商中绑定时,我应该 运行 查询数据库吗?

Should I run database queries while binding in a Laravel Service Provider?

以下基本上是我现在所拥有的,并且似乎可以正常工作。但是我发现有人说您不应该 运行 服务提供商中的数据库查询,因为可能还没有注册所有内容。以这种方式进行配置是否存在潜在问题?如果是这样,是否有另一种方法来设置类似的情况,即我从数据库中获取配置数据?

我最初是使用配置文件来绑定我想要的对象的实例

config/payment.php

'test' => array(
    'terminalid' => env('TERMINAL'),
    'secret' => env('SECRET'),
),

注册方法中的PaymentServiceProvider

  public function register()
  {
      $this->app->bind(Gateway::class, function ($app) {
          $gateway = new Gateway();
          return $gateway->initialize([
              config('payment.test')
          ]);
      });
  }

但我想将其更改为基于数据库查询的配置。

设置table

license terminal secret
test ABC123 XXXX
demo ZYX987 XXXY

所以像这样

  public function register()
  {
      $this->app->bind(Gateway::class, function ($app) {
          $setting = Setting::where("id",request()->id)->first();
          $gateway = new Gateway();
          return $gateway->initialize([
              'terminalid' => $setting->terminal,
              'secret' => $setting->secret,
          ]);
      });
  }

我认为您可以将代码从 register 方法移动到 boot 方法

public function boot() {
   $this->app->bind(Gateway::class, function ($app) {
      $setting = Setting::where("id",request()->id)->first();
      $gateway = new Gateway();
      return $gateway->initialize([
         'terminalid' => $setting->terminal,
         'secret' => $setting->secret,
      ]);
   });         
}

因此,您将确保所有需要的服务都已注册

这可能会迟到,但我认为它有一天可能会帮助一个神奇的灵魂。

根据 laravel documentation 和@nickc 的贡献,它适用于服务提供商 class 的 boot method 中的 运行 代码。 但是,正如您解释的那样,关于依赖于另一个服务提供商的服务提供商,您希望从数据库中读取配置。根据我的发现,无论订单注册如何,所有注册的提供商都不一定可用。

注册的顺序很重要。

这是我的测试代码:

` /* * 应用服务提供商... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class,

    App\Providers\SchoolServiceProvider::class,

in my test AppServiceProvider depends on SchoolServiceProvider and SchoolServiceProvider depends onIlluminate\Database\DatabaseServiceProvider::class,` 位于提供商列表的顶部。在我切换顺序并解决问题之前,这种方法没有用。

` /* * 应用服务提供商... */ App\Providers\SchoolServiceProvider::class,

    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    // App\Providers\BroadcastServiceProvider::class,
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,

` 我不知道为什么会这样,但这是我的发现。