メインコンテンツへスキップ
パッケージからデータベース接続を拡張するには、生成方法の登録と利用する接続の選択を分けます。インストールしただけでアプリケーションの既定接続や、すべてのMySQL接続を置き換えない設計にします。 このページはLaravel Framework v13.40.0 の公式実装を確認しています。接続設定の基本はデータベース設定、プロバイダーの読み込みはパッケージの自動検出を参照してください。

拡張点を選ぶ

データベースの生成処理には、異なる範囲の拡張点があります。 DB::extend() に渡すコールバックの戻り値はPDOやQuery Builderではなく、Illuminate\Database\Connection です。DatabaseManager::configure() がこのクラスを要求します。
データベースの extend() は、共通の Illuminate\Support\Manager と同じ呼び出し規約ではありません。コールバックの第1引数はアプリケーションコンテナではなく、接続設定の配列です。ほかのドライバー拡張の例をそのまま流用しないでください。

接続名の拡張がドライバー名より優先される

DatabaseManager::makeConnection() は、設定を取得してから次の順で生成方法を選びます。
  • DB::extend('reporting', ...) は、database.connections.reporting に対して適用されます。
  • DB::extend('mysql', ...) は、接続名側に拡張がない、driver が mysql の接続へ適用されます。
  • どちらも同じ拡張レジストリを使います。接続名とドライバー名の衝突も考慮して、パッケージ固有の名前を使います。
  • extend() は設定配列を作りません。拡張だけ登録しても、指定した名前の接続設定がなければ例外になります。

独自ドライバー名を明示的に選ぶ

次は独自名 acme-sqlite を、標準SQLite接続の生成へ橋渡しする最小例です。新しいDBプロトコルやSQL方言を実装する例ではありません。独自アダプターを配布する際の、登録と選択の境界を示します。 Acme\DatabaseBridge\ がComposerのPSR-4で src/ に対応する構成を想定し、src/DatabaseBridgeServiceProvider.php に配置します。
db.factory はLaravelが共有する ConnectionFactory のバインディングです。標準Factoryを直接呼ぶため、DatabaseManagerの拡張選択に戻らず、SQLiteの遅延PDO生成とConnection生成を再利用できます。 このコールバックは初回の接続解決時に実行されます。プロバイダーの boot() は生成方法の登録だけを行い、接続テストやマイグレーションを実行しません。通常の非遅延プロバイダーとして、対象接続が初めて解決される前に読み込ませます。 利用アプリケーションは、config/database.php の既存の connections 配列へ接続を追加します。既定の default は変更しません。
SQLiteファイルを事前に用意し、書き込み権限を確認してから利用します。パッケージを読み込んだだけでファイルを作成する設計にはしません。
利用者が渡すのは接続名 acme_reports であり、ドライバー名 acme-sqlite ではありません。例ではFactoryへ渡す前に driver を sqlite へ変換するため、生成後の getDriverName() も sqlite です。
resolverの中から DB::connection($name) を呼び直すと、まだ保持されていない同じ接続の生成に戻ります。再帰を避けるため、Factoryや独自アダプターでConnectionを生成します。

Connectionサブクラスへの置き換えは別の範囲

既存ドライバーのConnectionクラス自体を置き換える場合は、Connection::resolverFor() があります。コールバックには、即座に接続済みのPDOではなく、PDOを遅延生成するClosureが渡る場合もあります。 ただし、この登録はConnectionクラスのstaticプロパティに保持されます。sqlite に登録すれば、標準Factoryで新しく作るSQLite接続全体へ影響し、上の acme-sqlite の例も対象になります。接続名1つだけの置き換えとしては扱えません。
  • コールバックでは対象DB用のConnectionサブクラスを返します。基底Connectionだけでは、DB固有のGrammarやProcessorなどを保てません。
  • Factoryは createConnector() と createConnection() を分けています。resolverFor() の登録だけで、未知のドライバーのPDOコネクターまで提供されるわけではありません。
  • DB::extend() の独自resolverが標準Factoryを使わなければ、Factory内の resolverFor() の確認も通りません。
  • 同じドライバーへの再登録は上書きです。ほかのパッケージとの競合と、同一PHPプロセス内のテストへの持ち越しを確認します。
影響を限定したいパッケージは、まず固有の接続名・ドライバー名による DB::extend() を検討します。

reconnectとpurgeを区別する

DatabaseManagerは、生成済みConnectionを接続名ごとに保持します。設定やresolverを変更しても、すでに生成された接続には自動反映されません。 特に reconnect() は、保持済みConnectionのクラスや設定配列を丸ごと置き換えるAPIではありません。拡張クラスや接続設定の変更を反映したい場合は、処理中のトランザクションがない安全なタイミングで purge() した後、新しい接続を取得します。
purge() は、別のサービスや変数が保持しているConnection参照を新しいものに差し替えません。また、接続名の ::read・::write・::direct は別の保持キーになるため、基底名をpurgeするだけで、それらも一括削除されるとは考えないでください。テナント切り替えなどを目的に、実行中の共有接続設定を安易に書き換えないでください。長寿命ワーカーでは、設定キャッシュの更新だけでなくプロセスの再起動と、保持済みサービスへの影響も確認します。

パッケージの登録と生成をテストする

Orchestra Testbenchでは、プロバイダーを読み込み、独自ドライバーを実際に選択します。次は tests/DatabaseBridgeTest.php の例です。実行環境にはPDOとSQLiteドライバーが必要です。
:memory: は接続の切断で内容が失われるため、このテストはテーブルやデータの保持を期待しません。実際のパッケージでは、次も追加します。
  • 接続名のresolverがドライバー名のresolverより優先されること。
  • 同名の再登録と forgetExtension() が、生成済みConnectionを置き換えないこと。
  • 必須設定が欠けた場合の例外と、接続失敗時の挙動。
  • 対応DBでのマイグレーション、トランザクション、read/write分離など、提供を約束する機能。
  • 長寿命ワーカーや複数パッケージとの併用で、登録や接続状態が混ざらないこと。

保守時の確認項目

  • 独自名でオプトインし、既定接続や組み込みドライバーを黙って上書きしていないか。
  • configキャッシュにClosureや接続オブジェクトを入れず、生成処理はプロバイダーに置いているか。
  • 接続先や認証情報を信頼できるアプリケーション設定として管理しているか。
  • extend() の引数、Factoryの生成順、reconnect() の転送対象をサポート対象のLaravelで再確認したか。
  • 設定変更後の再生成手順とワーカー再起動を利用者へ案内しているか。

関連ページ

参照した一次情報

最終更新日 2026年11月3日