如何设置 YII2 Multiple DB Configurable?

How to set YII2 Multiple DB Configurable?

如何在活动记录中设置数据库可配置?

这是我的文件: app\models\multi_db\Devices;

<?php
namespace app\models\multi_db;

use yii\db\ActiveRecord;

class Devices extends ActiveRecord
{ 
     private static $dbConn;

     public function __construct($config=[])
     {
        switch ($config['server']) {
        case '2':
            self::$dbConn = \Yii::$app->dbtwo;
            break;
        case '3':
            self::$dbConn = \Yii::$app->dbthree;
            break;          
        default:
            self::$dbConn = \Yii::$app->dbone;
            break;
        }
     }

     public static function getDb()
     {
        return self::$dbConn;
     }

     public function findDevice($id)
     {
        return self::findOne($id);
     }
}

这是我获取设备的代码:

$model = new Devices(['server' => 3]);
$device = $model->findDevice(1);

但这会产生错误:

Undefined index: server

我认为 findDevice 方法中没有设置构造函数?

我该如何解决这个问题?

你好像搞错了,

如果您使用 findOne(id) 意味着您将从数据库中检索值。 当你应该这样创造你 server

$model = new Device();
$model->server = 3;
$model->save();

你在 switch 中也有错误(你 select 总是相同的 db ..dbtwo )认为你应该分配不同的 db (dbOne, dbTwo, dbthree)

class Devices extends ActiveRecord
{ 
 private static $dbConn;

 public function __construct($config=[])
 {
    switch ($config['server']) {
    case '2':
        self::$dbConn = \Yii::$app->dbtwo;
        break;
    case '3':
        self::$dbConn = \Yii::$app->dbthree;
        break;          
    default:
        self::$dbConn = \Yii::$app->dbone;
        break;
    }
 }

 public static function getDb()
 {
    return self::$dbConn;
 }

 public function findDevice($id)
 {
    return self::findOne($id);
 }
}

好吧,findOne() 将在不提供服务器配置的情况下使用您的构造函数,这就是您收到此错误的原因,您可以简单地尝试:

public function __construct($config=[])
{
    if (isset($config['server'])) switch ($config['server']) {
        case '2':
            self::$dbConn = \Yii::$app->dbtwo;
            break;
        case '3':
            self::$dbConn = \Yii::$app->dbthree;
            break;          
        default:
            self::$dbConn = \Yii::$app->dbone;
            break;
    }
    // don't forget to call parent constructor
    parent::__construct($config);
}

但我认为这里的逻辑是错误的,这应该使用静态方法来设置,例如:

class Devices extends ActiveRecord
{

    private static $dbConn;

    public static function setServer($id)
    {
        switch ($id) {
            case '2':
                self::$dbConn = \Yii::$app->dbtwo;
                break;
            case '3':
                self::$dbConn = \Yii::$app->dbthree;
                break;          
            default:
                self::$dbConn = \Yii::$app->dbone;
                break;
        }
    }

    public static function getDb()
    {
        if (self::$dbConn===null)
            self::$dbConn = \Yii::$app->dbone;

        return self::$dbConn;
    }

}

然后:

// find device on dbone
$device = Devices::findOne(1);

// find device on dbtwo
Devices::setServer(2);
$device = Devices::findOne(1);