🐻

Laravel で database.php を編集せずに接続先を増やす

2023/07/05に公開

staging環境のデータベースをRDSでスナップショットから復元したのでstaging環境からtinkerで接続したいけどdatabase.phpは編集したくない!
そんなニッチな需要にお答えします。

日々運用していくと稀にオペレーションで過去のデータを復元して調査する場合があります。
RDSで運用しているとスナップショットデータからインスタンスを立てる事で気軽に過去データの環境ができあがります。
あとは新規に立てた復元環境に接続してデータを確認するだけです。

しかしSQLだけでは調査が終わらず、スクリプトを実行して確認したい時があります。
そんな時は復元環境の接続情報をdatabase.phpに追記したり既存値を上書きする事で対応します。
が、追記や上書きをせずにtinkerで実行するスクリプトでのみ接続先を増やして処理したい…みたいな時の手法です。

前提

  • 新規に接続したいデータベースは既存のデータベースと接続ユーザー情報は同一で、接続先のホスト名のみが違う
  • database.php に新規の接続先を追記するのが難しい or 編集したくない

コード

sample.php
<?php

function run(): void
{
    config(['database.connections.temp' => array_replace_recursive(config('database.connections.mysql'), [
        'read' => [
            'host' => 'xxxxx-cluster.cluster-ro-xxxxx.ap-northeast-1.rds.amazonaws.com',
        ],
        'write' => [
            'host' => 'xxxxx-cluster.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com',
        ],
        'host' => 'xxxxx-cluster.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com',
    ])]);

    DB::connection('temp')->table('xxxxx')->get();
}
$ vi /path/to/sample.php
$ cd /path/to/project/root
$ php artisan /path/to/sample.php
>>> run()

説明

config('database.connections.mysql') で既存の接続を取得します。
その上でarray_replace_recursiveにより、各host名を上書きしたい値にすることで既存値からhost名のみ変更した配列が出来上がります。

array_replace_recursive(config('database.connections.mysql') , [
    'read' => [
        'host' => 'xxxxx-cluster.cluster-ro-xxxxx.ap-northeast-1.rds.amazonaws.com',
    ],
    'write' => [
        'host' => 'xxxxx-cluster.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com',
    ],
    'host' => 'xxxxx-cluster.cluster-xxxxx.ap-northeast-1.rds.amazonaws.com',
])

configに新規接続先として追加します。
config('database.connections.temp')でデータを確認すると既存の接続情報からhost名だけ変更された新規接続先が取得できます。

config(['database.connections.temp' =>[...]])

あとは通常のDB操作に対してconnectionで追加した接続情報を指定してあげれば復元した環境に対して接続できます。

DB::connection('temp')->table('xxxxx')->get();
TANOMU

Discussion