ServiceProvider を読み、設定をパッケージの公開APIとして保守する方法を整理します。パッケージ開発の基礎を前提とし、実装の確認には laravel/framework の v13.34.0 を使用しています。
公開とマージは別の処理
publishes() はコピー元とコピー先を登録します。vendor:publish がファイルをコピーするまで、利用者の config ディレクトリは変わりません。一方、mergeConfigFrom() は起動時の設定リポジトリを更新し、ファイル自体を書き換えません。
register() のマージでデフォルト値が使われます。
mergeConfigFrom()は最上位だけをマージする
ServiceProvider::mergeConfigFrom() は、パッケージの設定を先に、アプリケーションの既存設定を後に渡して array_merge() を実行します。同じ文字列キーでは、アプリケーション側の値が優先されます。
以下はフレームワークのマージ処理を配列だけで再現した例です。
enabled は補われますが、transport は配列全体が置き換わります。transport.retries は残りません。利用者が古い transport 配列を公開済みなら、新しいキーを同じ配列に追加しても補完されない点が重要です。
replaceConfigRecursivelyFrom()でネストした設定を補う
Laravel 13のServiceProvider には、protectedメソッドの replaceConfigRecursivelyFrom() もあります。こちらは同じ順序で array_replace_recursive() を実行します。
ネストした文字列キーを個別に上書きする設定APIにしたい場合は、プロバイダーの register() を次のように変更します。同じ設定キーに対して、先ほどの mergeConfigFrom() と併用する必要はありません。
$defaults と $overrides を使うと、結果は次のようになります。
replaceConfigRecursivelyFrom() は、このページで確認したLaravel 13のソースコードに存在するメソッドです。公式のパッケージ開発ドキュメントが紹介する mergeConfigFrom() と区別し、対応するフレームワークの実装を確認して利用してください。数値キーのリストは全体置換にならない
再帰的な置換は「配列をすべて利用者の値に差し替える」処理ではありません。数値キーでも同じキーの値を置き換え、利用者が指定しなかったキーは残します。['slack'] だけを指定しても、database が残ります。また、['channels' => []] を渡してもデフォルトのリストは空になりません。通知先やミドルウェアなど、リスト全体の指定に意味がある設定では特に注意してください。
このような設定を持つ場合は、リストと部分上書き可能な連想配列を別の最上位キーに分けて浅いマージを使うなど、設定の構造から検討します。すでに公開したパッケージでマージ方式を変更すると、同じ設定ファイルでも挙動が変わるため、単なる実装の置き換えとして扱わないでください。
設定キャッシュにはマージ後の値が保存される
両メソッドは、アプリケーションがCachesConfiguration を実装し、configurationIsCached() が true の場合にはマージ処理をスキップします。通常のLaravelアプリケーションでは、設定キャッシュが存在する起動がこれに該当します。
ConfigCacheCommand は古い設定キャッシュを削除し、新しいアプリケーションを起動して設定リポジトリ全体を取得します。その起動でプロバイダーの設定がマージされ、結果がキャッシュファイルに保存されます。以降の起動では LoadConfiguration がその値を読み込みます。
したがって、パッケージを更新してデフォルト値やマージ方式が変わっても、古いキャッシュを使い続けるアプリケーションには反映されません。設定キャッシュを利用するデプロイでは、更新後のコードで再構築します。
php artisan config:clear を使います。キャッシュの生成場所を独自に決めず、Laravelのコマンドに管理を任せてください。
設定変更をリリースする前の確認
パッケージのテストでは、未公開の設定だけでなく、旧バージョンから残っている設定を入力として扱います。- 設定未公開でも、必要なデフォルト値が取得できる。
- 古い公開済み設定で、利用者の値が優先され、新しい項目が設計どおり補われる。
- ネストした配列、数値キーのリスト、空配列について、上書きの契約が変わらない。
- 利用アプリケーションで
config:cacheが成功し、キャッシュを使う別の起動でも同じ設定になる。
関連ページ
パッケージのテスト
サービスプロバイダーを登録して、設定やサービスの動作を検証します。
バージョン互換性管理
公開APIの変更をリリース方針と継続的なメンテナンスに結び付けます。