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

Yii 框架 CArrayDataProvider 與 CActiveDataProvider 區別詳解及適用場景

     編輯:PHP 相關知識

Yii 框架 CArrayDataProvider 與 CActiveDataProvider 區別詳解及適用場景

在 Yii 1.x 開發中,CArrayDataProvider 與 CActiveDataProvider 是兩大核心數據提供者,廣泛用於 CGridView、CListView 等數據展示組件。本文通過實例對比兩者的數據來源、適用場景、配置差異,助您精準選型。

一、核心區別速覽表

維度CArrayDataProviderCActiveDataProvider
數據來源PHP 數組(任意結構)ActiveRecord 模型類(關聯數據庫表)
典型場景非 AR 數據:外部 API、多表聯查、臨時計算、緩存數組基於單表或關聯表的 AR 模型查詢
分頁/排序需手動處理或配置 pagination/sort內建支持 criteria、pagination、sort
性能特點全量數組載入內存,大數據量慎用配合 CDbCriteria 可生成高效 SQL(含 LIMIT/OFFSET)

二、CArrayDataProvider 實戰示例

場景:從另一個數據庫連接(marketdb)查詢 tbl_count2 表,結果以數組形式返回,需分頁展示。

// 1. 執行原生 SQL 查詢(跨庫/複雜聯查/存儲過程等)
$sql  = "SELECT * FROM tbl_count2 ORDER BY id DESC";
$data = Yii::app()->marketdb->createCommand($sql)->queryAll(); // 返回二維數組

// 2. 封裝為 CArrayDataProvider
$dataProvider = new CArrayDataProvider($data, array(
    'pagination' => array(
        'pageSize' => 16, // 每頁 16 條
    ),
    // 可選:啟用排序
    'sort' => array(
        'attributes' => array('id', 'name', 'created_at'),
        'defaultOrder' => 'id DESC',
    ),
));

// 3. 視圖中直接傳給 CGridView
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider,
    'columns' => array('id', 'name', 'count', 'created_at'),
));

關鍵注意點

  • 內存風險:queryAll() 會將所有結果載入內存。若源表超過萬行,請改用 query() 返回 CDbDataReader 迭代處理,或在 SQL 層面做 LIMIT。
  • 排序邏輯:數組排序由 PHP 完成,大數據量性能遠遜於數據庫 ORDER BY。

三、CActiveDataProvider 實戰示例

場景:基於 PhotoAttachment 模型,按條件篩選、倒序分頁。

$condition = array();
// 構建條件數組,例如:
// $condition[] = "status = 1";
// $condition[] = "user_id = " . Yii::app()->user->:id;

$dataProvider = new CActiveDataProvider('PhotoAttachment', array(
    'pagination' => array(
        'pageSize' => 20,
    ),
    'criteria' => array(
        'condition' => implode(' AND ', $condition), // WHERE 子句
        'order'     => 'id DESC',                    // ORDER BY
        // 'with' => array('author'),                 // 急加載關聯(可選)
    ),
));

優勢亮點

  • SQL 級分頁:自動生成 LIMIT 20 OFFSET 0,內存常數級
  • 關聯查詢:with 支持急加載,避免 N+1 問題
  • 無縫集成:CGridView 自動讀取 sort、pagination 參數生成分頁鏈接

四、選型決策樹

需要展示的數據來源是否為 ActiveRecord 模型?
├── 是 → 直接使用 CActiveDataProvider
│   ├── 需要複雜關聯查詢?→ 配合 criteria.with 使用
│   ├── 需要自定義 SELECT 字段?→ criteria.select = 'id, name'
│   └── 需要動態條件構建?→ 使用 CDbCriteria 對象構建
└── 否(數組/外部API/多表聯查結果/緩存數據)
    ├── 數據量 < 5000 行?→ CArrayDataProvider 可接受
    │   └── 需要排序/分頁?→ 配置 sort/pagination 參數
    └── 數據量 ≥ 5000 行?
        ├── 能否推到 SQL 層做 LIMIT?→ 改用 CSqlDataProvider
        └── 必須全量 PHP 處理?→ 考慮分批處理/異步隊列/緩存預計算

五、進階補充:CSqlDataProvider

若需「原生 SQL 查詢」+「數據庫級分頁/排序」,CSqlDataProvider 是更佳選擇:

$count = Yii::app()->db->createCommand("SELECT COUNT(*) FROM tbl_count2 WHERE status=1")->queryScalar();

$dataProvider = new CSqlDataProvider(
    "SELECT * FROM tbl_count2 WHERE status=1 ORDER BY id DESC",
    array(
        'totalItemCount' => $count,
        'pagination' => array('pageSize' => 16),
        'sort' => array('attributes' => array('id', 'name')),
    )
);

CSqlDataProvider 會自動在 SQL 外層包裹 LIMIT/OFFSET,兼具靈活性與性能。

六、總結

  • CActiveDataProvider:首選,面向 AR 模型,性能最優,功能最全
  • CArrayDataProvider:備選,面向 PHP 數組,適合小數據量、非 AR 場景
  • CSqlDataProvider:專選,面向原生 SQL,兼顧靈活查詢與 DB 級分頁

實際開發中,80%+ 場景使用 CActiveDataProvider;跨庫報表、臨時計算結果展示用 CArrayDataProvider;複雜報表 SQL 直出用 CSqlDataProvider。

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