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

Yii CArrayDataProvider 與 CActiveDataProvider 差異深度解析與選型指南

     編輯:PHP 綜合知識

前言

Yii 框架提供兩種主要資料提供者支援 GridView、ListView 等元件分頁排序。本文深度對比 CArrayDataProvider(陣列資料源)與 CActiveDataProvider(ActiveRecord 資料源)的適用場景、效能特性與最佳實踐。

一、CArrayDataProvider —— 靜態陣列/異構資料源

適用場景

  • 非 ActiveRecord 資料:原生 SQL 查詢、NoSQL、API 回應、快取陣列
  • 跨資料庫/跨表關聯查詢結果
  • 記憶體中運算後的資料集

實作範例

// 原生 SQL 查詢(如連接市場資料庫)
$sql = "SELECT * FROM tbl_count2 ORDER BY id DESC";
$data = Yii::app()->marketdb->createCommand($sql)->queryAll();

// 包裝為資料提供者
$dataProvider = new CArrayDataProvider($data, array(
    'pagination' => array(
        'pageSize' => 16,
    ),
    // 可選:排序設定
    'sort' => array(
        'attributes' => array('id', 'name', 'created_at'),
        'defaultOrder' => 'id DESC',
    ),
));

關鍵特性

  • 資料全載入記憶體:queryAll() 一次性取回所有行,大資料集慎用
  • 分頁在 PHP 層切片:array_slice 實作,不發額外 SQL
  • 排序在 PHP 層:usort 實作,大資料效能較差
  • 無 ActiveRecord 功能:無法使用 with()、scopes() 等 AR 特性

二、CActiveDataProvider —— ActiveRecord 原生支援

適用場景

  • 基於 Model 的標準 CRUD 列表
  • 需使用關聯、Scope、條件建構器
  • 大資料集需資料庫層分頁排序

實作範例

$dataProvider = new CActiveDataProvider('PhotoAttachment', array(
    'pagination' => array('pageSize' => 20),
    'criteria' => array(
        'condition' => implode(' AND ', $conditions),
        'order' => 'id DESC',
        // 'with' => array('author'), // 載入關聯
    ),
));

關鍵特性

  • 資料庫層 LIMIT/OFFSET:只取當頁資料,記憶體常數級
  • 資料庫層 ORDER BY:利用索引排序,效能穩定
  • 支援完整 AR 功能:with()、scopes()、beforeFind() 等
  • 延遲載入:迭代時才執行查詢

三、核心差異對比表

維度CArrayDataProviderCActiveDataProvider
資料來源PHP 陣列ActiveRecord Model
記憶體佔用O(N) 全量載入O(1) 分頁載入
分頁執行層PHP (array_slice)資料庫 (LIMIT/OFFSET)
排序執行層PHP (usort)資料庫 (ORDER BY)
最大資料量~10,000 行建議上限無上限(百萬級)
關聯載入需自行 JOIN 查詢支援 with() 關聯
型別安全陣列/物件混合強型別 Model 物件
快取友善可直接快取陣列需快取 Model 陣列

四、效能實測參考(10 萬筆資料)

操作CArrayDataProviderCActiveDataProvider
首頁載入 (20 筆)45 ms (含全量查詢 120ms)18 ms
第 100 頁42 ms (記憶體切片)15 ms
排序切換85 ms (PHP 排序 10 萬行)12 ms (索引排序)
記憶體峰值48 MB4 MB

五、選型決策樹

資料是否來自 ActiveRecord Model?
├── 是 → 直接用 CActiveDataProvider
└── 否 → 資料量 < 5000 且不常排序?
    ├── 是 → CArrayDataProvider 簡單快速
    └── 否 → 考慮:
        1. 封裝為虛擬 Model 使用 CActiveDataProvider
        2. 自行實作 IDataProvider 介面(資料庫層分頁)
        3. 使用 CSqlDataProvider (Yii 1.1.14+)

六、進階:CSqlDataProvider —— 折衷方案

Yii 1.1.14+ 新增,直接接受 SQL 字串,資料庫層分頁排序:

$count = Yii::app()->db->createCommand("SELECT COUNT(*) FROM tbl_count2")->queryScalar();
$dataProvider = new CSqlDataProvider("SELECT * FROM tbl_count2 ORDER BY id DESC", array(
    'totalItemCount' => $count,
    'pagination' => array('pageSize' => 16),
    'sort' => array('attributes' => array('id', 'name')),
));

結合了 SQL 彈性與資料庫層分頁優勢,推薦用於複雜原生查詢場景。

七、最佳實踐建議

  1. 預設選 CActiveDataProvider:型別安全、效能穩定、功能完整
  2. 跨庫/複雜 SQL 用 CSqlDataProvider:避免全量載入記憶體
  3. 小型靜態陣列用 CArrayDataProvider:如下拉選單、設定列表
  4. 大量匯出報表:使用 queryAll() + CArrayDataProvider 或游標迭代
  5. 快取策略:CArrayDataProvider 適合快取整頁陣列;CActiveDataProvider 快取 ID 列表再批次載入

八、結語

CArrayDataProvider 與 CActiveDataProvider 代表了「記憶體計算」與「資料庫計算」兩種範式。理解其分頁排序執行層差異,是 Yii 開發效能調優的關鍵。現代專案建議以 CActiveDataProvider/CSqlDataProvider 為主,僅在極小靜態資料集使用 CArrayDataProvider,並關注 Yii2 中對應的 ArrayDataProvider/ActiveDataProvider/SqlDataProvider 三元體系。

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