3

我有一个 Yii2 模型,它使用具有相同结构的多个表。表名将根据登录的用户而改变,并且表名非常独特,并且取决于用户名。我将如何动态地将这个表名分配给模型?到目前为止我已经这样做了。

在我的模型中:

    protected $table;

    public function __construct($table)
    {
    $this->table='custom_risk_assignment_table';//logic to obtain the table name goes here
    }

    public static function tableName()
    {
    return $this->table;
    }

但是这样做会导致错误Using $this when not in object context,因为function tableName()它是一个static函数。

那我该怎么做?任何帮助表示赞赏。在此先感谢!

编辑:详细图片

假设我有一个来自 ABC 公司的用户。我的应用程序中有很多进程,比如 PQR 就是其中之一。如果来自公司 ABC 的用户登录并选择流程 PQR,如果不存在,我需要在我的数据库中创建一个表 ABC_PQR,或者如果它已经创建,则加载该表。我需要这个表名到我的模型中。同样可能存在用户和许多进程。管理数据库的最佳方法是什么。

4

3 回答 3

5

由于tableName是静态方法(正是错误消息所说的),因此您无权访问非静态属性。(不能使用$this关键字)

所以你必须声明一个静态属性:

protected static $table;

public function __construct($table)
{
    self::$table = $table;
}

public static function tableName()
{
    return self::$table;
}

/* UPDATE */
public static function setTableName($table)
{
    self::$table = $table;
}

更新:

好吧我的错。如果您调用诸如 等静态方法,则不会调用构造函数updateAllfind并且$table不会被设置。所以你有不同的选择。

  1. 在使用静态数据库操作方法之前手动调用构造函数。
  2. 向模型添加一个静态设置器,public static function setTableName($tableName)并在每次成功登录时调用它。
于 2014-05-09T07:32:21.863 回答
1

摆脱这种情况的一种方法是不改变返回值,tableName而是为不同的表使用不同的类。这些类仅在实现方面有所不同tableName

abstract class Foo extends ActiveRecord
{
    // your existing code goes here

    abstract function tableName();
}

class FooOne extends Foo
{
    function tableName() { return 'table1'; }
}

class FooTwo extends Foo
{
    function tableName() { return 'table2'; }
}

然后,在您的应用程序中的某个适当位置,您将决定要使用哪个表并记住该表的模型是什么。就像是:

if ($username == "anne") {
    $fooModel = new FooOne();
}
else if ($username == "bob") {
    $fooModel = new FooTwo();
}

在此之后,您可以简单地$fooModel用作调用目标,查询将自动影响相应的表。例如:

$foos = $fooModel::findAll();
于 2014-05-09T09:36:13.820 回答
1

这个问题搞了很久,但是我也只是看到了这个问题,有了一些想法,希望对后来的人有所帮助。

通过构造函数动态设置表名是不友好的。我们可以通过设置工厂方法来绑定表名,例如:

class MyTableModel extends \yii\db\ActiveRecord {

    protected static $table;

    public static function useTable($table) {
        static::$table = $table;

        return new static();
    }

    public static function tableName() {
        return static::$table;
    }
}

使用时,通过 绑定表名useTable,例如:

// find
MyTableModel::useTable('tableName1')::find()->where(...)->all(); // use tableName1
MyTableModel::useTable('tableName1')::findAll(); // use tableName1
MyTableModel::useTable('tableName1')::updateAll(); // use tableName1

MyTableModel::useTable('tableName2')::findAll(); // use tableName2

// create 
$table = MyTableModel::useTable('tableName2');
$table->attributes = $attributes;
$table->save()

使用该useTable方法实现完全绑定的目标。

请注意,这不是通过闭包完成的,而是设置MyTableModel::$table静态变量的值。所以useTable多次调用会使用最后一次设置的值

于 2018-12-03T11:27:30.993 回答