在控制器中我想更改我的默认数据库连接,这样我就可以访问不同的数据库。它曾经工作,我在AppController中创建了一个函数,在需要时在每个控制器中调用它,包含以下内容:
ConnectionManager::config('database', [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => $username,
'password' => $password,
'database' => $database,
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
]);
ConnectionManager::alias('database', 'default');
我创建了一个新的数据库连接,称之为'database',并且别名默认为此连接,这样将使用此连接而不是默认连接。但是,当我打印
$this->{$modelName}->connection()->config();
它仍然提供默认连接。并且表示该表不存在的错误确认我不在新连接的数据库中。
答案 0 :(得分:0)
即时连接通常可以正常工作,但模型/表类只在实例化时才会自行获取连接。
因此,如果它不适用于特定的表,这很可能是因为它已经被实例化并获取了默认连接(表注册表只为每个别名实例化一个表类)。
因此,要么确保之后正在实例化表,如果需要在请求后期创建别名,则可能需要清除(TableRegistry::clear()
)/从注册表中删除TableRegistry::remove()
循环(但是可能会导致其他问题,因为您可能会松动可能应用的动态配置),或者手动设置所涉及的表的连接:
\Cake\Datasource\ConnectionManager::alias('database', 'default');
$connection = \Cake\Datasource\ConnectionManager::get('default');
$this->{$modelName}->setConnection($connection); // connection() before CakePHP 3.4
如果您需要在多个或所有表格中使用此功能,或者您只是想从控制器转移责任(它很可能不应过度参与配置模型层),那么可能需要调度创建别名时的事件,使用基表类或侦听事件的行为,甚至可能使用"服务"知道表并相应地更新表连接。
\Cake\Datasource\ConnectionManager::alias('database', 'default');
$connection = \Cake\Datasource\ConnectionManager::get('default');
$event = new \Cake\Event\Event('Connection.aliased', $connection, ['source' => 'default']);
\Cake\Event\EventManager::instance()->dispatch($event);
例如,在表格中,您可以执行类似的操作,在表格配置为使用已设置别名的连接(即defaultConnectionName() === 'default'
时)应用新连接,然后选择新连接:
\Cake\Event\EventManager::instance()->on(
'Connection.aliased',
function (\Cake\Event\Event $event) {
// data() before CakePHP 3.4
if ($event->getData('source') === static::defaultConnectionName()) {
$this->setConnection($event->getSubject()); // subject() before CakePHP 3.4
}
}
);
另见
答案 1 :(得分:0)
我基于会话变量构建了一个具有动态连接的示例项目。 我希望有人觉得它有用: https://github.com/jszoja/cakephp3-multidb
我在那里记录了。