遊戲平台、多租戶系統等常有需求:資料庫中表數量不固定、依業務動態建立,無法預先用 GII 產生 Model。需執行期獲取所有表名並統一操作。
// 獲取指定資料庫連線的所有表名
$sql = "SHOW TABLES";
$tables = Yii::app()->db_order->createCommand($sql)->queryAll();
// $tables 為陣列:[['Tables_in_dbname' => 'table1'], ['Tables_in_dbname' => 'table2'], ...]
// 遍歷處理每張表
foreach ($tables as $row) {
$tableName = array_values($row)[0]; // 取得表名
// 動態查詢該表資料
$data = Yii::app()->db_order->createCommand()
->select('*')
->from($tableName)
->where('user_id=:uid', [':uid' => $userId])
->queryAll();
// 處理 $data...
}
'components' => [
'db' => [ // 主資料庫
'class' => 'CDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=main_db',
'username' => 'root',
'password' => '',
'tablePrefix' => 'tbl_',
],
'db_order' => [ // 訂單資料庫
'class' => 'CDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=order_db',
'username' => 'root',
'password' => '',
'tablePrefix' => 'ord_',
],
'db_query' => [ ... ], // 查詢資料庫
'db_log' => [ ... ], // 日誌資料庫
],
class OrderController extends Controller {
public function actionUserOrders($userId) {
// 使用 db_order 連線
$tables = Yii::app()->db_order->createCommand("SHOW TABLES")->queryAll();
$allOrders = [];
foreach ($tables as $row) {
$table = array_values($row)[0];
$orders = Yii::app()->db_order->createCommand()
->select('order_id, amount, created_at')
->from($table)
->where('user_id=:uid', [':uid' => $userId])
->queryAll();
$allOrders = array_merge($allOrders, $orders);
}
$this->render('userOrders', ['orders' => $allOrders]);
}
}
搭配上一篇的 DTable 可獲得 ActiveRecord 風格操作:
foreach ($tables as $row) {
$table = array_values($row)[0];
$model = new DTable($table); // 或 DTable::model($table)
$orders = $model->findAllByAttributes(['user_id' => $userId]);
// ...
}
/^[a-zA-Z0-9_]+$/。autoConnect=false 按需連線,避免閒置連線佔用資源。// Yii 2.0
$tables = Yii::$app->db_order->getSchema()->getTableNames();
// 或
$tables = Yii::$app->db_order->createCommand('SHOW TABLES')->queryColumn();
foreach ($tables as $table) {
// 動態模型需繼承 ActiveRecord 並覆寫 tableName()
$modelClass = new class($table) extends \yii\db\ActiveRecord {
private $table;
public function __construct($table) { $this->table = $table; parent::__construct(); }
public static function tableName() { return $this->table; } // 注意:靜態方法無法存取 $this
};
// 正確做法:使用匿名類別搭配靜態屬性或工廠模式
}
Yii 1.x 透過 SHOW TABLES + CDbCommand + 多資料庫元件配置,即可靈活實現動態表操作,適合遊戲、日誌、多租戶等動態表結構場景。