CakePHP 3 动态数据库连接
CakePHP 3 dynamic database connection
我想在控制器中更改我的默认数据库连接,以便我可以访问不同的数据库。它曾经有效,我在 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();
它仍然给出默认连接。一个错误说 table 不存在,确认我不在新连接的数据库中。
别名仅在 table 实例化时间
动态连接通常工作正常,但模型/table classes 仅在实例化时自行拾取连接一次。
因此,如果它不适用于特定的 table,这很可能是因为它已经被实例化并获得了默认连接(table 注册表仅实例化了一个 table class 每个别名一次)。
因此,要么确保 table 之后被实例化,如果别名需要,这可能需要清除 (TableRegistry::clear()
)/从 (TableRegistry::remove()
) 注册表中删除在请求周期的后期创建(但是这可能会导致其他问题,因为您可能会丢失可能应用的动态配置),或者手动设置所涉及的 table(s) 上的连接:
\Cake\Datasource\ConnectionManager::alias('database', 'default');
$connection = \Cake\Datasource\ConnectionManager::get('default');
$this->{$modelName}->setConnection($connection); // connection() before CakePHP 3.4
以更自动化的方式动态应用连接
如果您需要在多个或所有 table 上使用它,或者如果您只是想从控制器转移责任(它很可能不应该过度参与配置模型层),然后可能会在创建别名时分派一个事件,并使用基础 table class 或侦听该事件的行为,或者甚至可能使用了解 tables 并相应地更新 tables 连接。
\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);
例如,在 table 中,您可以执行类似的操作,应用新连接以防 table 配置为使用已别名的连接,即如果 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
}
}
);
另见
我构建了一个基于会话变量的动态连接示例项目。
我希望有人觉得它有用:
https://github.com/jszoja/cakephp3-multidb
我在那里记录了它。
我想在控制器中更改我的默认数据库连接,以便我可以访问不同的数据库。它曾经有效,我在 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();
它仍然给出默认连接。一个错误说 table 不存在,确认我不在新连接的数据库中。
别名仅在 table 实例化时间
动态连接通常工作正常,但模型/table classes 仅在实例化时自行拾取连接一次。
因此,如果它不适用于特定的 table,这很可能是因为它已经被实例化并获得了默认连接(table 注册表仅实例化了一个 table class 每个别名一次)。
因此,要么确保 table 之后被实例化,如果别名需要,这可能需要清除 (TableRegistry::clear()
)/从 (TableRegistry::remove()
) 注册表中删除在请求周期的后期创建(但是这可能会导致其他问题,因为您可能会丢失可能应用的动态配置),或者手动设置所涉及的 table(s) 上的连接:
\Cake\Datasource\ConnectionManager::alias('database', 'default');
$connection = \Cake\Datasource\ConnectionManager::get('default');
$this->{$modelName}->setConnection($connection); // connection() before CakePHP 3.4
以更自动化的方式动态应用连接
如果您需要在多个或所有 table 上使用它,或者如果您只是想从控制器转移责任(它很可能不应该过度参与配置模型层),然后可能会在创建别名时分派一个事件,并使用基础 table class 或侦听该事件的行为,或者甚至可能使用了解 tables 并相应地更新 tables 连接。
\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);
例如,在 table 中,您可以执行类似的操作,应用新连接以防 table 配置为使用已别名的连接,即如果 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
}
}
);
另见
我构建了一个基于会话变量的动态连接示例项目。 我希望有人觉得它有用: https://github.com/jszoja/cakephp3-multidb
我在那里记录了它。