Yii 的 Model 是 MVC 架構中資料邏輯的核心。本文系統整理 Model 常用屬性、生命週期方法、Active Record (AR) 操作、關聯查詢與效能優化技巧,幫助開發者掌握資料層開發精髓。
| 屬性/方法 | 用途 | 說明 |
|---|---|---|
| tableName() | 指定資料表 | 回傳字串,如 'gshop_order_ext' |
| rules() | 驗證規則 | 定義欄位驗證邏輯 |
| relations() | 關聯關係 | 定義 BELONGS_TO、HAS_MANY 等關聯 |
| attributeLabels() | 欄位標籤 | 表單顯示友善名稱 |
| safeAttributes() | 大量賦值白名單 | Yii 1.1 必設,Yii 2.0 改用 rules() 中 safe 驗證器 |
| beforeValidate/afterValidate | 驗證前後鉤子 | 需回傳 true 才繼續流程 |
| beforeSave/afterSave | 儲存前後鉤子 | 常用於時間戳自動填充、資料加密等 |
// 新增
$model = new User;
$model->name = 'John';
$model->save(); // 等同 insert()
// 修改
$model = User::model()->findByPk(1);
$model->name = 'Jane';
$model->save(); // 等同 update()
// 刪除
$model = User::model()->findByPk(1);
$model->delete();
// 驗證(不寫入資料庫)
if ($model->validate()) { /* ... */ }
| 方法 | 參數型態 | 回傳型態 | 適用場景 |
|---|---|---|---|
| findByPk() | 主鍵值 / 陣列 | 單一 Model 實例 | 精確查詢單筆 |
| findByAttributes() | 條件陣列 | 單一 Model 實例 | 依非主鍵欄位查單筆 |
| findAllByAttributes() | 條件陣列 | Model 陣列 | 依條件查多筆 |
| findAll() | CDbCriteria 物件 | Model 陣列 | 複雜查詢、分頁、排序 |
$criteria = new CDbCriteria;
$criteria->condition = "title LIKE :keyword";
$criteria->params = array(':keyword' => '%php%');
$criteria->order = 'created_time DESC';
$criteria->limit = 10;
$criteria->select = 'id, title, content'; // 僅選取需要欄位,減少傳輸
$articles = Article::model()->findAll($criteria);
// $articles 為 Article 物件陣列,可直接 $article->title 存取
Yii 預設使用 Lazy Load(延遲載入),存取關聯屬性時才發出 SQL。若在列表頁需顯示關聯資料,會產生 N+1 查詢問題。
// 一次查詢撈取文章與分類
$articles = Article::model()->with('category')->findAll();
// 在 view 中直接存取,不再觸發額外 SQL
foreach ($articles as $article) {
echo $article->category->name; // 已預載入
}
public function relations() {
return array(
'category' => array(self::BELONGS_TO, 'Category', 'category_id'),
'tags' => array(self::MANY_MANY, 'Tag', 'article_tag(article_id, tag_id)'),
'comments' => array(self::HAS_MANY, 'Comment', 'article_id'),
);
}
select 避免 SELECT *。condition 中的欄位應建立索引。CPagination 使用 limit/offset。with() 避免 N+1 問題。cache() 方法可快取 AR 查詢結果。