Yii动态数据库连接根据用户而定?

Yii动态数据库连接根据用户而定?,yii,Yii,我的项目是基于多租户 我有多个客户(公司),每个客户都有多个用户 每个客户端都有自己的数据库,因此在用户身份验证期间,我会发现该用户的关联数据库的名称 每个数据库的结构都是相同的。。。只有数据不同 这样我们就可以为不同的公司保留不同的数据库,而不会在数据库中混入数据 在编写应用程序时,客户端的数量(因此数据库的数量)是未知的,因此不可能在引导脚本中包含所有连接 现在,我想做的是,动态地改变引导中的DB连接,或者能够动态地为用户登录创建一个新连接。在Yii中是否有一个简单的解决方案,并且仍然使用A

我的项目是基于多租户

我有多个客户(公司),每个客户都有多个用户

每个客户端都有自己的数据库,因此在用户身份验证期间,我会发现该用户的关联数据库的名称

每个数据库的结构都是相同的。。。只有数据不同

这样我们就可以为不同的公司保留不同的数据库,而不会在数据库中混入数据

在编写应用程序时,客户端的数量(因此数据库的数量)是未知的,因此不可能在引导脚本中包含所有连接

现在,我想做的是,动态地改变引导中的DB连接,或者能够动态地为用户登录创建一个新连接。在Yii中是否有一个简单的解决方案,并且仍然使用AR,查询生成器

yii论坛上也提出了同样的问题,但仍然没有明确回答,。。。。
你可以在这里找到这个问题

我会和论坛上的羌一样做。您需要一个db连接列表和登录用户的属性,该属性位于
Yii::app()->user
,告诉您要使用哪个连接(例如,我将其命名为
connectionId
)。 然后在ActiveRecord基类中覆盖
getDbConnection()

public function getDbConnection()
{
    if(self::$db!==null)
        return self::$db;
    else
    {
        // list of connections is an array of CDbConnection configurations indexed by connectionId
        $listOfConnections=/* to be loaded somehow */;
        // create DB connection based on your spec here:
        self::$db=new CDbConnection($listOfConnections[Yii::app()->user->connectionId]);
        self::$db->active=true;
        return self::$db;
    }
}

谢谢你的宝贵帮助

对于我的应用程序,我需要多个数据库

a) 包含公司所有信息的主数据库,称为“projectmaster”

b) sa公司“company1”的数据库

因此,我在yii\framework\db\ar\CActiveRecord.php中实现了如下代码:

self::$db=Yii::app()->getDb();
if(self::$db instanceof CDbConnection)
{
    $db=Yii::app()->db;
    $constring=array();
    $constring=$db->createCommand()
        ->select('dbname,host,dbusername,dbpassword')
        ->from('projectmaster')
        ->where('company_name =company1')
        ->queryRow();
    self::$db=new CDbConnection('mysql:host='.$constring['host'].';dbname='.$constring['dbname'],$constring['dbusername'],$constring['dbpassword']);

self::$db->active=true;
return self::$db;
}

在这里,我使用现有连接创建新的连接对象“self::$db”, 这是覆盖旧连接还是创建新连接

当我必须使用“createCommand()”进行某些数据提取时,我没有使用活动记录类

所以那时候我是连接对象

$connection=Yii::app()->db; $command=$connection->createCommand($sql)

这里我得到的是yii创建的旧连接“$connection”。。。。 但对于应用程序,它应该使用新的连接,以便从“company1”数据库获取数据


所以我想创建一个可重用的连接。当我们想使用自定义查询时,是否可以更改YII连接或每次都必须创建新连接。

不确定我的答案是否及时到达@Gaurish,但几天前我遇到了完全相同的问题,这就是我解决问题的方法

简而言之,您应该扩展CActiveRecord类,不仅覆盖getDbConnection(),还覆盖类构造函数和model()函数

class SuperRecord extends CActiveRecord {

public static $host;
public static $port;
public static $user;
public static $pass;

public static $connection = null;

function __construct($dbName = null, $scenario='insert') {
    if ($tenant != null) {
         Yii::app()->params['activeDb'] = $dbName;
    }
    self::$host = Yii::app()->params['defaultDbHost'];
    self::$port = Yii::app()->params['defaultDbPort'];
    self::$user = Yii::app()->params['superDbUser'];
    self::$pass = Yii::app()->params['suPassword'];
    parent::__construct($scenario);
    Yii::app()->params['activeDb'] = ''; //destruct sensitive data after using
}

public function getDbConnection() {
    if(self::$connection!==null)
        return self::$connection;
    else
    {
        $connectionString = 'mysql:host='.self::$host.';port='.self::$port.';dbname='.Yii::app()->params['activeDb'];
        self::$connection=new CDbConnection($connectionString, self::$user, self::$pass);
        self::$connection->emulatePrepare = true;
        self::$connection->charset = 'utf8';
        self::$connection->active=true;
        if(self::$connection instanceof CDbConnection)
            return self::$connection;
        else
            throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));
    }
}

public static function superModel($dbName, $className=__CLASS__) {
    Yii::app()->params['activeDb'] = $dbName;
    return self::model($className);
}

public static function model($className=__CLASS__)
{
    return parent::model($className);
}
}
之后,您将能够创建连接到数据库的任何模型,并将其名称发送给构造函数,如下所示:

$messagesModel = new UserMessages($databaseName);
或者:

$messages = UserMessages::superModel($databaseName)->findAll();
看看这个,我已经尽可能清楚地解释了

Yii::app()->db->setActive(false)

Yii::app()->db->connectionString='mysql:host=localhost;dbname='.trim($databasename)

Yii::app()->db->setActive(true)

明白了

首先,我有一个名为companyMainDb的主数据库,它有所有的用户信息以及他们的公司id

每个公司都有不同的数据库,命名为company\u company\u id

第1步:

      Go to web/index.php
第二步:

      Go to web/index.php
像这样改变它

require(__DIR__ . '/../vendor/autoload.php');
Dotenv::load(__DIR__ . '/../');

// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', getenv('YII_ENV'));

require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

$config = require(__DIR__ . '/../config/web.php');
新的yii\web\Application($config)

Yii:$app->user->isGuest?$dbName='companyMainDb':$dbName='company'.Yii:$app->user->identity->company\u id

$config['components']['db']=['class'=>'yii\db\Connection','dsn' =>mysql:host='.getenv('DB_host')。;dbname='.$dbname,'username'=>getenv('DB_USER'),'password'=>getenv('DB_password'),'charset'=>utf8',]