Dynamic database connection in Symfony

Viewed 264

I have a second entity manager, and i want to get parameters from a database and change the DATABASE_URL to connect to another database.

# config/packages/doctrine.yaml
my_entity:
    url: '%DATABASE_URL%'
    driver: 'pdo_mysql'
    server_version: '5.7'
    charset: utf8mb4

I try to add a parameter from the process function from Kernel.php, but it's apparently run only one time.

1 Answers

This can be done by changing the data of the Connection class. You need to create your own Connection class and hook it up to the project.

Let's create the required class Connection

// src/Doctrine/DatabaseConnection.php

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;

class DatabaseConnection extends Connection
{

    public function __construct(array $params, Driver $driver, $config, $eventManager )
    {
        // First, let symfony connect to the default database from env so that a Connection instance appears in order to execute a sql query to get the necessary data
        parent::__construct($params, $driver, $config, $eventManager);

        // Getting data and changing it
        $user_database =  $this->executeQuery('SELECT * FROM database WHERE user_id = :user_id',['user_id'=>1])->fetch();
        $params['dbname'] = $user_database['dbname'];
        $params['user'] =  $user_database['user'];
        $params['password'] = $user_database['password'];
        parent::__construct($params, $driver, $config, $eventManager);

    }
}

Note: As you can see in the example, to begin with, we connect to our main database from .env so that we can access the desired database by executing an sql query. After receiving the data, we modify it and call the parent's constructor method again to replace the Connection instance with the database we want.

Initialize DatabaseConnection

# config/packages/doctrine.yaml
doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        wrapper_class: App\Doctrine\DatabaseConnection

Note: Here we have connected our handler using the DBAL wrapperClass option

Related