In Yii2, you can use the same model to interact with different databases by overriding the default database connection in the model. Here’s how you can configure a model to work with multiple databases dynamically.

Steps to Use the Same Model for Different Databases in Yii2

Step 1: Define the Default Database in config/db.php

You should already have a default database connection configured in your config/db.php file, which the model will use unless you override it.

return [
‘class’ => ‘yii\db\Connection’,
‘dsn’ => ‘mysql:host=localhost;dbname=default_db’,
‘username’ => ‘root’,
‘password’ => ”,
‘charset’ => ‘utf8’,
];

Step 2: Create a Base Model with Dynamic Database Connection

Create a base model class that overrides the getDb() method to dynamically set the database connection. All your models can extend from this base class to share the same functionality.

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

class BaseModel extends ActiveRecord
{
public static $databaseName = null;

/**
* Override getDb() to switch the database dynamically.
*/
public static function getDb()
{
if (self::$databaseName) {
// Create a new connection to the specified database
return Yii::createObject([
‘class’ => ‘yii\db\Connection’,
‘dsn’ => ‘mysql:host=localhost;dbname=’ . self::$databaseName,
‘username’ => ‘root’,
‘password’ => ”,
‘charset’ => ‘utf8’,
]);
}

// Default database connection
return Yii::$app->db;
}

/**
* Set the database dynamically before using the model.
*/
public static function setDatabase($dbName)
{
self::$databaseName = $dbName;
}
}

Step 3: Extend Your Models from BaseModel

Now, you can extend your specific models from this BaseModel. For example:

namespace app\models;

class User extends BaseModel
{
public static function tableName()
{
return ‘user’; // table name remains the same
}
}

Step 4: Dynamically Switch Database in Code

Whenever you want to switch to a different database for a model, you can call the setDatabase() method before using the model:

use app\models\User;

// Switch to ‘database1’
User::setDatabase(‘database1’);

// Querying the ‘user’ table in ‘database1’
$users = User::find()->all();

// Switch to ‘database2’
User::setDatabase(‘database2’);

// Querying the ‘user’ table in ‘database2’
$usersFromDb2 = User::find()->all();

In this example, the User model is used for different databases by setting the $databaseName property dynamically.

Step 5: Reset Database to Default

If you want to revert back to the default database, you can simply reset the $databaseName property to null:

User::setDatabase(null);

Now, the User model will use the default database connection configured in config/db.php.

Optional: Handling Multiple Database Configurations

If you have multiple database configurations stored somewhere (e.g., configuration array), you can modify the getDb() method to fetch the configuration dynamically.

public static function getDb()
{
if (self::$databaseName) {
$dbConfig = [
‘db1’ => [
‘dsn’ => ‘mysql:host=localhost;dbname=db1’,
‘username’ => ‘root’,
‘password’ => ”,
],
‘db2’ => [
‘dsn’ => ‘mysql:host=localhost;dbname=db2’,
‘username’ => ‘root’,
‘password’ => ”,
],
];

if (isset($dbConfig[self::$databaseName])) {
return Yii::createObject(array_merge([
‘class’ => ‘yii\db\Connection’,
‘charset’ => ‘utf8’,
], $dbConfig[self::$databaseName]));
}
}

// Default database connection
return Yii::$app->db;
}

Conclusion

By overriding the getDb() method in a base model and using a static property to hold the current database name, you can easily switch between different databases using the same model in Yii2. This approach is flexible and maintains a clean separation between database logic and application logic.

Share!

Shares