Laravelにおいて設定ファイル、Viewファイル、Artisanコマンドといった抽象的な部分、基礎的な部分の定義はファイル配置で指定されています。データベース定義を/config/database.php以外に記述しても、/resources/views以下の外にViewファイルを作っても、/app/Console/Command以下以外にArtisanコマンドを定義しても、自動で読み込んではくれません。この自動読み込みの制約はLaravelを使用したプロジェクトならば、このフォルダにこの目的のファイルがある、と確信を持って行動できるためとても役に立ちます。しかしながらこの制約を無視したい時もあります。例えば、ライブラリの開発です。/packages以下にライブラリのコードを全てまとめたいのですが、まとめてしまったら自動読み込みが走りません。そこでサービスプロバイダにおける後付けの機能の読み込み、登録が必要になります。
サービスプロバイダは、Laravelアプリケーション全体の起動処理における、初めの心臓部です。皆さんのアプリケーションと同じく、Laravelのコアサービス全部もサービスプロバイダを利用し、初期起動処理を行っています。
サービスプロバイダ 6.x Laravel
サービスプロバイダは上記の引用の通り、Laravel起動時の自動実行処理です。心臓部とあるので誤解しがちな文章ですがサービスプロバイダはプロバイダの種類を指し示す語です。複数のサービスプロバイダが起動時に実行されます。この記事では後付けしたいコードをまとめたサービスプロバイダを用意して、その用意したサービスプロバイダをLaravelに登録することで後付けでconfig, データベース接続を追加します。
任意のファイルによるconfigの追加ですが読み込み自体は原始的なPHPのコードが最適です。Laravelの内部でも実際これですしOKでしょう。既存設定を上書きする時は(new Provider)->appからいまどこに何が入っているか調べるのが良いでしょう。コードは次になります。
// pk/config/hoge.php
return [
'connection' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE_HOGE', 'hoge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter(
[
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]
) : [],
],
];
// pk/Providers/HogeProvide.php
class HogeProvider {
public function boot(): void
{
// php artisan vendor:publishで出力されるコンフィグファイルの候補として登録
$this->publishes(
[
__DIR__.'/config/hoge.php' => config_path('hoge.php'),
]
);
// 登録メソッド呼び出し
$this->registerDataBaseConnect();
}
private function registerDataBaseConnect(): void
{
// Configの設定。読み込んでConfigファサードから有無を聞いて、なければ設定をする。
$DS = DIRECTORY_SEPARATOR;
// requireでファイルのロードをする
$conf = Config::get('hoge') ?? require __DIR__.$DS.'config'.$DS.'hoge.php';
Config::set('hoge', $conf);
// DB接続の追加設定。
// Laravelの読み込まれた設定はLaravelアプリケーションインスタンスに保持される
// Laravelアプリケーションインスタンスはシングルトンインスタンスであり、各Providerのappプロパティからアクセスできる
// 既に定義済みのDB接続設定database.connectionsに読み込んだhoge.connectionに記述されたDB接続設定を追加して上書きする
$this->app['config']['database.connections'] = Arr::add(
$this->app['config']['database.connections'],
'hoge',
config('hoge.connection')
);
}
}