Должен ли я выполнять запросы к базе данных при привязке к поставщику услуг Laravel?

Ниже в основном то, что у меня есть прямо сейчас, и, похоже, это работает. Но я нашел людей, говорящих, что вы не должны запускать запросы к базе данных в поставщике услуг, потому что еще не все может быть зарегистрировано. Существуют ли потенциальные проблемы с выполнением конфигурации таким образом? И если да, то есть ли альтернативный способ настроить аналогичную ситуацию, когда я получаю данные конфигурации из базы данных?

Первоначально я использовал файл конфигурации для привязки экземпляра объекта, который я хотел

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')
          ]);
      });
  }

Но я хочу изменить это, чтобы настроить конфигурацию на основе запроса к базе данных.

Таблица настроек

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,
          ]);
      });
  }

person nickc    schedule 08.12.2020    source источник
comment
Я скорее удивляюсь, почему вы хотели бы сделать это таким образом. Конфигурации обычно привязаны к среде, и их предпочтительно выполнять с помощью переменных среды или другого типа глобальной конфигурации.   -  person Tommie    schedule 08.12.2020
comment
У нас есть динамический список компаний, где все одинаково, кроме их учетных данных на шлюзе. Я бы оставил все как массивы конфигурации, но мы добавляем компании достаточно часто, чтобы записи базы данных кажутся более подходящими.   -  person nickc    schedule 08.12.2020
comment
Ах вот так, я думаю, было бы лучше создать промежуточное программное обеспечение для этого. Предполагая, что вы действуете по запросу, а не по созданию экземпляра (по крайней мере, в этом случае использования это так).   -  person Tommie    schedule 08.12.2020
comment
Да, я использую переменную запроса, чтобы определить, какую конфигурацию использовать. Что было бы эквивалентом промежуточного программного обеспечения? Могу ли я добавить конфигурацию в качестве переменной в запросе?   -  person nickc    schedule 08.12.2020
comment
Промежуточное ПО фактически действует по запросу. Таким образом, у вас есть все необходимые переменные запроса без необходимости вызова вспомогательных функций. И это позволило бы прервать запрос, в любом случае что-то пойдет не так. Что было бы более подходящим для загрузки динамических конфигураций в этом случае использования. Перехват запроса и действия по нему были бы более безопасными. Поскольку вы будете вызывать его только тогда, когда вам это нужно, вместо того, чтобы всегда присутствовать в вашем приложении.   -  person Tommie    schedule 09.12.2020


Ответы (2)


Я думаю, вы можете переместить код из метода 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,
      ]);
   });         
}

Таким образом, вы будете уверены, что все необходимые сервисы уже зарегистрированы

person Ilyas    schedule 08.12.2020
comment
Насколько я понимаю, метод загрузки запускается после запуска всех методов регистрации. Так что это должно работать. Есть ли какие-либо потенциальные побочные эффекты от использования этого метода или вещей? - person nickc; 08.12.2020
comment
Насколько я знаю, нет никаких побочных эффектов от этого. Это просто необычно. Потому что предполагается, что вы регистрируете (bind(), singleton()) в методе register и выполняете некоторую инициализацию в методе boot(). Но в вашем случае вам нужно какое-то динамическое поведение, так что все должно быть в порядке. - person Ilyas; 09.12.2020

Возможно, это уже поздно, но я думаю, что когда-нибудь это может помочь чудо-душе.

Согласно документации laravel и вкладу @nickc, целесообразно запустить код в boot method класса поставщика услуг. однако в отношении поставщика услуг, который зависит от другого поставщика услуг, как вы объяснили, вы хотите прочитать конфигурации из базы данных. По моим выводам, не обязательно верно, что все зарегистрированные провайдеры будут доступны независимо от регистрации заказа.

Порядок регистрации очень важен.

вот мой тестовый код:

` /* * Поставщики услуг приложений... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::класс,

    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,

` Я не знаю почему, но это моя находка.

person Tetranyble    schedule 21.05.2021