2014-05-09 49 views
3

我有一個使用多個表具有相同結構的Yii2模型。表名將根據用戶登錄而改變,表名是非常獨特的,並取決於用戶名。我將如何動態地將此表名稱分配給模型?我迄今已完成此操作。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(如果不存在),或者在已經創建的表中加載表。我需要將這個表名稱放入我的模型中。同樣,用戶和許多進程也在那裏。管理數據庫的最佳方法是什麼?

+0

根據某些運行時檢查在同一個數據庫中使用不同的表可能是實現此目的最糟糕的方式。我們在談論多少個不同的表名? – Jon

+0

@Jon單個表中的所有數據都需要更多的時間來查詢!我爲單個用戶提供了超過12個自定義表格。 –

+0

你有沒有考慮過單獨的數據庫?無論如何,這不是你應該樂意做的事情的最佳論據是你將面臨的問題的數量。 – Jon

回答

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; 
} 

UPDATE:

好吧我的錯。如果調用類似updateAll,find等的靜態方法,構造函數將不會被調用。而$table將不會被設置。所以你有不同的選擇。

  1. 在使用靜態數據庫操作方法之前手動調用構造函數。
  2. 在模型中添加靜態設置器,如public static function setTableName($tableName),並在每次成功登錄時調用它。
+0

錯誤消失了!但是'return self :: $ table'仍然是空的。 :-( –

+0

看到我的更新.. – bitWorking

+0

其實我無法在每次成功登錄時自動執行它,因爲我有很多自定義表格。我只需要在用戶需要時指定表格! –

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(); 
+0

謝謝jon.But對不起,我不能理解你的觀點。 Bcoz,在這裏我也需要得到獨特的表名正確嗎?我的表名將以用戶名開始。我將如何更改它?另外,由於我的用戶超過100個,爲每個人編寫不同的類是否實用? –

+0

@ DencyGB:這是應該與問題一起出現的一種重要細節。我不能說最好的解決方案是什麼(事實上,這個解決方案是不實際的),但我可以這樣說:你正在進入花哨的領域。 **小心**。 – Jon

+0

:對不起,在提問中不提及它。我真的不知道如何處理這種情況,或者不管我是否重新設計數據庫。希望有人會分享他們的想法。 –