databaseyii2dsn

yii2 change database dynamically


I'm trying to move to another database dynamically. I've seen several questions that showed change db files from one to another and they just getting some information from next database. But what I need is completely moving to second database. How should I do this? I've seen that in order to achieve this dsn (in db.php file) should be altered. But I changed it and it's still not changed?? I should have full access to second database closing first one. Give me advice please


Solution

  • Configs like db.php are not intended to be changed in process (while PHP is processing). They are loaded once in the initialization, when request is entered the framework. As an alternative, you can configure second DB beforehand in db.php, and change between them dynamically like:

    Yii::$app->db // your default Database
    

    and

    Yii::$app->db2 // Second configured Database, to which you can switch dynamically later
    

    You can learn about multiple database connections here

    So, if you want ActiveRecord(for instance User) to be able to access two databases, you can define some static variable, which specifies from which DB to read/write. For example:

    class User extends \yii\db\ActiveRecord
    {
        const DB_DATABASE1 = 'db1';
        const DB_DATABASE2 = 'db2';
    
        private static $db = self::DB_DATABASE1;
    
        public static function setDb($db)
        {
            self::$db = $db;
        }
    
        public static function getDb()
        {
            switch (self::$db) {
                case self::DB_DATABASE1:
                    return Yii::$app->db;
                case self::DB_DATABASE2:
                    return Yii::$app->db2;
                default:
                    throw new \Exception("Database is not selected");
            }
        }
    
        //...
    

    And then use it in Controller like:

    User::setDb(User::DB_DATABASE1);
    $usersDB1 = User::find()->all();
    
    User::setDb(User::DB_DATABASE2);
    $usersDB2 = User::find()->all();