Search code examples
laraveldatabase-connectionconfigmulti-database-connections

Connecting to a different database in Laravel based on connection url


I've been tasked with making our Laravel code connect to a different database as the main database when the url is different. Our website is accessible by 2 urls:

a.mycompany.com and b.mycompany.com

I know the main database connection details are configured in config/database.php, but I've read that it's very much discouraged to try to conditionally change config variables there. Nonetheless, if I wanted to, could I check for the current url and change the connection details in that file? How would I do that?


Solution

  • For these purposes, you need to configure the necessary connections in config/database.php. For example, for MySQL, add two connections:

    'mysql_1' => [
                'driver' => 'mysql',
                'url' => env('DATABASE_URL'),
                'host' => env('DB_HOST', '127.0.0.1'),
                'port' => env('DB_PORT', '3306'),
                'database' => env('DB_DATABASE', 'forge'),
                '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'),
                ]) : [],
            ],
    
    'mysql_2' => [
                'driver' => 'mysql',
                'url' => env('DATABASE_URL'),
                'host' => env('DB_HOST', '127.0.0.1'),
                'port' => env('DB_PORT', '3306'),
                'database' => env('DB_DATABASE', 'forge'),
                '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'),
                ]) : [],
            ],
    

    Then directly in the code, use the desired connection:

    $siteOne = DB::connection('mysql_1')->select(/* ... */);
    
    $siteTwo = DB::connection('mysql_2')->select(/* ... */);
    
    $siteTwo = (new User)->setConnection('mysql_2')->find(1);
    
    

    To determine which domain it is, you can use suddomain routing:

    Route::domain('{domain}.mycompany.com')->group(function () {
        // $domain variable
    });
    

    Then use $domain to check which site it is and use the correct connection.

    It is also possible to establish a model-specific connection using the $connection property:

    protected $connection = 'mysql_2';