这是我的情况。
我在“主”数据库中有使用我的应用程序的所有诊所的列表。在“主目录”中,有关每个诊所的信息在一个表中,该表中还包含用于数据库的数据库名称,用户名和密码的列。每个架构的结构都相同。
所有这些诊所将使用我目前在Yii2中开发的单一源代码。我需要的是在登录时自动选择相应的数据库,所有交易必须都在数据库中。
我尝试在会话中保存数据库名称。
$db_name = "main";
if( isset($_SESSION['db']) ){
$db_name = $_SESSION['db'];
}
$config = [
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname='.$db_name,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
];
它不起作用,我无法在config / main.php中访问会话。
我无法执行解决方案,因为所有诊所都具有相同的SERVER_NAME。 Change DB connection Dynamically
答案 0 :(得分:0)
如果您有一个“主”数据库,然后将主数据库连接记录用于第二个数据库: 最好将db2配置为NULL db连接,然后:
'db' => $db, // default...,
'db2' => [
// Fill with null values
],
Yii::$app->db2->dsn= 'DSN';
Yii::$app->db2->username = 'username';
# password...
此外,首先关闭db2连接。 close()
。请务必销毁
此link 还有一个好方法。 Dynamic database connection
或尝试以下操作:
'db2' => function () {
if (!\Yii::$app->user->isGuest) {
$db_name = \Yii::$app->user->getid();
} else {
$db_name = ..; params
}
return Yii::createObject([
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=' . $db_name,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
},
然后:
public static function getDb()
{
return Yii::$app->userDb;
}
当然,对于db(默认db),它可能不起作用。但是,如果经过测试..,请确保close()为先前的连接/
答案 1 :(得分:0)
我们有一个类似的配置,实际上我们有多个实例,一个实例可能具有一个主数据库以及一个或多个“子”数据库。主数据库有一个表,该表定义了子数据库,就像您的表一样。
我假设子数据库列在名为Children
的表中。
在Children
的模型中,我们有一些实用工具功能,我将在下面进行介绍。
子数据库中的表具有从class ChildActiveRecord extends \yii\db\ActiveRecord
扩展的模型类
然后子数据库中的任何表都使用
class SomeChildTable extends ChildActiveRecord
ChildActiveRecord
中的关键元素是getDb
,它覆盖了Yii的ActiveRecord类中定义的函数。 getDb
返回数据库连接。
Class ChildActiveRecord extends \yii\db\ActiveRecord {
public static function getDb()
{
$childDb = Children::getChild(); // usually set via Children->setChild()
// Does a connection already exist? Return it:
if(array_key_exists( $childDb, Yii::$app->params['dbs'])) {
return Yii::$app->params['dbs'][ $childDb ];
}
$child = Children::getChildDetails();
$connection = new \yii\db\Connection([
'dsn' => 'mysql:host=localhost;dbname=' . $child->dbName,
'username' => $child->username,
'password' => $child->password,
'charset' => 'utf8',
]);
Yii::$app->params['dbs'][ $childb ] = $connection; // cache for re-use
return $connection;
}
}
在我们的案例中,我们在配置文件中包含数据库用户和密码,以便可以对开发人员隐藏它们。
在children
表的模型类中:
Class Children extends \yii\db\ActiveRecord{
public function setChild()
{
Yii::$app->params['childdb'] = $this->dbname;
}
/**
* returns child db name
*
* @return string|null
*/
public static function getChild()
{
if( ! array_key_exists( 'childdb', Yii::$app->params ) ) return null;
return Yii::$app->params['childdb'];
}
/**
* @return Children|null
*/
public static function getChildDetails()
{
$childdb = self::getChild();
if( ! $childdb ) return null;
$child = self::findOne( ['dbname'=>$childdb]);
return $child;
}
在您的代码中,使用子数据库进行任何操作之前,您需要在Children表中找到子记录,例如
$child = Children::findOne([condition]);
然后设置子数据库:
$child->setChild();
之后,您可以使用常规Yii代码使用子数据库中的任何表。