Cakephp 3中的动态数据源和全局?

I have an application that will be used by many databases. To choose the database with the application data I have a database with the connections parameters (host, username, pass, database...)

The problem is that this dynamically created datasource does not work for the rest of the application.

Controller Code

$data       = $this->request->data;
$connection = ConnectionManager::get("default");
$query      = "SELECT * FROM clients WHERE client_id = ".$data['codigo'];
$result     = $connection->execute($query)->fetchAll('assoc');

ConnectionManager::drop('default');            

$config = ConnectionManager::config('connection', [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => $result[0]['host'],
        'username' => $result[0]['username'],
        'password' => $result[0]['password'],
        'database' => $result[0]['database'],
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'flags' => [],
        'cacheMetadata' => true,
        'log' => false,
        'quoteIdentifiers' => false,
        'url' => env('DATABASE_URL', null),
    ]);

$connection = ConnectionManager::get('connection');
ConnectionManager::alias('connection', 'default');

return $this->redirect(['controller' => 'Mains', 'action' => 'index']);

After this redirect, apparently the other controllers do not have this datasource.

It's certainly a bit unusual to be swapping databases based on contents inside request data - but generally database connection just needs to be done earlier on in Cake's initial setup, as each Controller's connection resource is already set to the default.

If you're only swapping the one time, you could manage this inside config/bootstrap.php (where Cake normally sets up it's ConnectionManager) instead.

You won't have access to $this->request, but could just grab it from $_REQUEST instead, for example:

In config/bootstrap.php, change these lines:

Cache::config(Configure::consume('Cache'));
ConnectionManager::config(Configure::consume('Datasources'));
Email::configTransport(Configure::consume('EmailTransport'));

To this:

Cache::config(Configure::consume('Cache'));

ConnectionManager::config(Configure::consume('Datasources'));
$connection = ConnectionManager::get("default");
$client = TableRegistry::get('Clients')->find()
    ->where(['client_id'=> $_REQUEST['client_id']])->firstOrFail();

ConnectionManager::drop('default');

$config = ConnectionManager::config('connection', [
    'className' => 'Cake\Database\Connection',
    'driver' => 'Cake\Database\Driver\Mysql',
    'persistent' => false,
    'host' => $client->host,
    'username' => $client->username,
    'password' => $client->password,
    'database' => $client->database,
    'encoding' => 'utf8',
    'timezone' => 'UTC',
    'flags' => [],
    'cacheMetadata' => true,
    'log' => false,
    'quoteIdentifiers' => false,
    'url' => env('DATABASE_URL', null),
]);

ConnectionManager::get('connection');

Email::configTransport(Configure::consume('EmailTransport'));

Edited: Switched from your raw SQL to a Table::find()