CDbCriteria 是 Yii 1.x 建構複雜 SQL 查詢的核心類別,提供物件導向的方式組合 WHERE、JOIN、ORDER、GROUP、LIMIT 等子句。本文系統整理 12 類常用操作,並附上可直接套用的程式碼範例。
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),
));
}
$criteria->compare('create_time', '<=' . $this->end_time); // 小於等於
$criteria->compare('price', '>=' . $minPrice); // 大於等於
$criteria->compare('status', '<>' . $excludeStatus); // 不等於
// 字串格式
$criteria->select = 'id, title, content, author, status, create_time';
// 陣列格式(推薦,IDE 友善)
$criteria->select = array('id', 'title', 'content', 'author', 'status', 'create_time');
// 簡單條件
$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 連接
$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)
$criteria->addSearchCondition('title', $keyword); // WHERE title LIKE '%keyword%'
$criteria->addSearchCondition('content', $keyword, true, 'OR', 'LIKE'); // 客製化
$criteria->addBetweenCondition('create_time', $startDate, $endDate); // AND 預設
$criteria->addBetweenCondition('price', 100, 500, 'OR'); // OR 連接
$criteria->join = 'LEFT JOIN {{users}} u ON u.id = t.author_id';
$criteria->select = 't.*, u.username, u.email'; // t 為主表別名(預設)
$criteria->order = 'create_time DESC, id ASC';
$criteria->group = 'category_id, status';
$criteria->having = 'COUNT(*) > 5';
$criteria->limit = 20; $criteria->offset = 0; // 或由 CPagination 自動管理
$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% 以上的查詢需求。建議將本文作為開發手邊的速查字典。