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

Yii CDbCriteria 完全指南:從基礎查詢到 JOIN、分組、統計的進階用法

     編輯:PHP 綜合知識

前言

CDbCriteria 是 Yii 1.x 建構複雜 SQL 查詢的核心類別,提供物件導向的方式組合 WHERE、JOIN、ORDER、GROUP、LIMIT 等子句。本文系統整理 12 類常用操作,並附上可直接套用的程式碼範例。

基礎查詢範例:模型 search() 方法

public function search() {
    $criteria = new CDbCriteria;
    $criteria->compare('id', $this->id);
    $criteria->compare('title', $this->title, true);   // true = LIKE 模糊比對
    $criteria->compare('content', $this->content, true);
    $criteria->compare('type', $this->type);
    $criteria->compare('user', $this->user, true);
    $criteria->compare('status', $this->status);
    $criteria->compare('create_date', $this->create_date, true);

    return new CActiveDataProvider($this, array(
        'criteria' => $criteria,
        'pagination' => array('pageSize' => 50),
    ));
}

12 大核心用法分類

1. 比較運算子

$criteria->compare('create_time', '<=' . $this->end_time); // 小於等於
$criteria->compare('price', '>=' . $minPrice);             // 大於等於
$criteria->compare('status', '<>' . $excludeStatus);       // 不等於

2. 指定查詢欄位

// 字串格式
$criteria->select = 'id, title, content, author, status, create_time';
// 陣列格式(推薦,IDE 友善)
$criteria->select = array('id', 'title', 'content', 'author', 'status', 'create_time');

3. 條件組合

// 簡單條件
$criteria->condition = 'status=1';
// 陣列條件(參數綁定,防 SQL 注入)
$criteria->condition = 'status=:status AND type=:type';
$criteria->params = array(':status' => 1, ':type' => 2);
// addCondition 追加(預設 AND)
$criteria->addCondition('is_deleted=0');
$criteria->addCondition('created_at > :date', 'OR'); // OR 連接

4. IN / NOT IN 查詢

$criteria->addInCondition('id', array(1,2,3,4,5));           // WHERE id IN (1,2,3,4,5)
$criteria->addNotInCondition('status', array(9, 99), 'OR');   // OR status NOT IN (9,99)

5. LIKE 模糊查詢

$criteria->addSearchCondition('title', $keyword);           // WHERE title LIKE '%keyword%'
$criteria->addSearchCondition('content', $keyword, true, 'OR', 'LIKE'); // 客製化

6. BETWEEN 區間查詢

$criteria->addBetweenCondition('create_time', $startDate, $endDate); // AND 預設
$criteria->addBetweenCondition('price', 100, 500, 'OR');             // OR 連接

7. JOIN 關聯查詢

$criteria->join = 'LEFT JOIN {{users}} u ON u.id = t.author_id';
$criteria->select = 't.*, u.username, u.email'; // t 為主表別名(預設)

8. 排序

$criteria->order = 'create_time DESC, id ASC';

9. 分組

$criteria->group = 'category_id, status';

10. HAVING 分組過濾

$criteria->having = 'COUNT(*) > 5';

11. LIMIT / OFFSET(分頁)

$criteria->limit = 20;
$criteria->offset = 0; // 或由 CPagination 自動管理

12. 與關聯查詢結合

$criteria->with = array(
    'author' => array('select' => 'username,email'),
    'comments' => array('condition' => 'comments.status=1', 'order' => 'create_time DESC'),
);

進階技巧:動態建構複雜查詢

public function buildCriteria($filters) {
    $criteria = new CDbCriteria;

    if (!empty($filters['keyword'])) {
        $criteria->addSearchCondition('title', $filters['keyword']);
        $criteria->addSearchCondition('content', $filters['keyword'], true, 'OR');
    }

    if (!empty($filters['category_id'])) {
        $criteria->compare('category_id', $filters['category_id']);
    }

    if (!empty($filters['date_range'])) {
        list($start, $end) = $filters['date_range'];
        $criteria->addBetweenCondition('create_time', $start, $end);
    }

    if (!empty($filters['status_list'])) {
        $criteria->addInCondition('status', $filters['status_list']);
    }

    $criteria->order = 'create_time DESC';
    return $criteria;
}

常見陷阱與避坑指南

  • ❌ $criteria->condition = "status=$status" → 直接拼接變數,SQL 注入風險。
    ✅ 使用 params 參數綁定或 compare()。
  • ❌ join 中未指定主表別名 → 欄位模糊導致錯誤。
    ✅ 明確使用 t.column 或自訂別名。
  • ❌ with 急載入大量關聯 → 產生龐大 SQL,記憶體暴增。
    ✅ 僅選擇必要關聯,或改用 join 手動控制。
  • ❌ 忘記 addCondition 的第二參數預設為 AND。
    ✅ 明確傳遞 'OR' 需要時。

相關專題推薦

熟練掌握 CDbCriteria 的 12 大核心用法,能讓你在不寫原生 SQL 的情況下,優雅地表達 95% 以上的查詢需求。建議將本文作為開發手邊的速查字典。

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