Yii动态数据库连接根据用户而定?
我的项目是基于多租户 我有多个客户(公司),每个客户都有多个用户 每个客户端都有自己的数据库,因此在用户身份验证期间,我会发现该用户的关联数据库的名称 每个数据库的结构都是相同的。。。只有数据不同 这样我们就可以为不同的公司保留不同的数据库,而不会在数据库中混入数据 在编写应用程序时,客户端的数量(因此数据库的数量)是未知的,因此不可能在引导脚本中包含所有连接 现在,我想做的是,动态地改变引导中的DB连接,或者能够动态地为用户登录创建一个新连接。在Yii中是否有一个简单的解决方案,并且仍然使用AR,查询生成器 yii论坛上也提出了同样的问题,但仍然没有明确回答,。。。。Yii动态数据库连接根据用户而定?,yii,Yii,我的项目是基于多租户 我有多个客户(公司),每个客户都有多个用户 每个客户端都有自己的数据库,因此在用户身份验证期间,我会发现该用户的关联数据库的名称 每个数据库的结构都是相同的。。。只有数据不同 这样我们就可以为不同的公司保留不同的数据库,而不会在数据库中混入数据 在编写应用程序时,客户端的数量(因此数据库的数量)是未知的,因此不可能在引导脚本中包含所有连接 现在,我想做的是,动态地改变引导中的DB连接,或者能够动态地为用户登录创建一个新连接。在Yii中是否有一个简单的解决方案,并且仍然使用A
你可以在这里找到这个问题我会和论坛上的羌一样做。您需要一个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',]