首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii 動態獲取資料庫所有表名並操作資料實作

     編輯:PHP 綜合知識

應用場景

遊戲平台、多租戶系統等常有需求:資料庫中表數量不固定、依業務動態建立,無法預先用 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...
}

多資料庫連線設定(config/main.php)

'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]);
    // ...
}

效能與安全考量

  • SHOW TABLES 效能:資訊表查詢較快,但頻繁呼叫建議快取表名列表(如 Redis 快取 1 小時)。
  • SQL 注入防護:表名無法用參數綁定,必須 白名單驗證 或正則檢查 /^[a-zA-Z0-9_]+$/。
  • 大量表查詢:若表數過百,逐表查詢會慢,考慮合併查詢(UNION ALL)或資料庫層面分區表。
  • 連線管理:多資料庫切換確保各元件 autoConnect=false 按需連線,避免閒置連線佔用資源。

Yii 2.0 對應寫法

// 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 + 多資料庫元件配置,即可靈活實現動態表操作,適合遊戲、日誌、多租戶等動態表結構場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved