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

Yii Framework 教程 (26):ActiveRecord 實戰範例 - ORM 基礎 CRUD 與關聯導航

     編輯:PHP 綜合知識

ActiveRecord 核心概念

  • 每個 AR 類對應一張資料表 (或視圖)。
  • 類屬性對應表欄位 (大小寫敏感,依資料庫 Schema)。
  • 實例對應表內單行資料。
  • CRUD 操作封裝為實例/靜態方法,極大簡化代碼。

定義 AR 類別


class Employee extends CActiveRecord {
    // 必須實現:靜態 model() 方法
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }
    
    // 必須實現:表名
    public function tableName() {
        return 'Employee';
    }
    
    // 可選:主鍵 (非 id 或複合鍵時)
    public function primaryKey() {
        return 'EmployeeId';
    }
    
    // 可選:關聯定義 (見教程 27)
    public function relations() { return []; }
    
    // 可選:驗證規則
    public function rules() { return []; }
}

導入 AR 類別 (批量導入)


// protected/config/main.php
'import' => [
    'application.models.*',
    // 'application.models.forms.*',
],

基礎 CRUD 操作

1. 讀取 (查詢)

方法用途回傳
find($condition, $params)符合條件第一行AR 實例 / null
findByPk($pk, $condition, $params)主鍵查詢AR 實例 / null
findByAttributes($attrs, $condition, $params)屬性值查詢AR 實例 / null
findBySql($sql, $params)自定義 SQL 查詢AR 實例 / null
findAll($condition, $params)所有符合行AR 實例陣列
findAllByPk($pks, $condition, $params)多主鍵查詢AR 實例陣列
findAllByAttributes($attrs, $condition, $params)多屬性值查詢AR 實例陣列
findAllBySql($sql, $params)自定義 SQL 多行AR 實例陣列
count($condition, $params)統計筆數整數
exists($condition, $params)是否存在布林值

範例:讀取所有員工


// Controller
public function actionIndex() {
    $model = Employee::model()->findAll();
    $this->render('index', ['model' => $model]);
}

// View (index.php)

    EmployeeId: EmployeeId; ?>
First Name: FirstName; ?>
Last Name: LastName; ?>
Title: Title; ?>
Address: Address; ?>
Email: Email; ?>
----------------------

2. 建立 (新增)


$employee = new Employee();
$employee->FirstName = 'James';
$employee->LastName = 'Shen';
$employee->Title = 'Developer';
$employee->Email = 'james.shen@example.com';
// ... 其他欄位
$employee->save(); // 自動判斷 INSERT/UPDATE

// 取得自增主鍵
echo $employee->EmployeeId;

3. 更新


$employee = Employee::model()->findByPk(1);
$employee->Title = 'Senior Developer';
$employee->save(); // 執行 UPDATE

4. 刪除


$employee = Employee::model()->findByPk(1);
$employee->delete(); // 執行 DELETE

// 或批次刪除
Employee::model()->deleteAll('Title=:title', [':title'=>'Intern']);

條件與參數詳細說明

  • $condition:SQL WHERE 子句字串,或陣列格式 ['column'=>value, 'column2'=>value2] (自動 AND 串接)。
  • $params:參數陣列,對應 $condition 中的佔位符 :param 或 ?。
  • 陣列格式條件支援運算子:['>', 'age', 18]、['in', 'id', [1,2,3]]、['like', 'name', '%John%']。

View 中存取欄位值

  • 直接屬性存取:$employee->FirstName (大小寫需與資料庫欄位一致)。
  • 格式化輸出:Yii::app()->dateFormatter->format('yyyy-MM-dd', $employee->BirthDate)。
  • 關聯導航 (需定義 relations):***$employee->manager->FirstName***。

常見問題與解決

問題原因解決
Property "Employee.xxx" is not defined欄位名大小寫不符、或表無此欄位確認資料庫 Schema、AR 類別屬性大小寫
save() 返回 false驗證失敗、唯一鍵衝突、欄位非空違規檢查 $employee->getErrors()、資料庫約束
findByPk 返回 null主鍵值不存在、型別不符 (字串 vs 整數)確認參數型別、資料確實存在
關聯導航報錯未定義 relations()、關聯類別名錯誤、外鍵欄位錯誤檢查 relations() 定義、參考教程 27

最佳實踐

  1. 在 model() 中使用 __CLASS__ 常數,支援繼承。
  2. 定義 primaryKey() 當主鍵非 id 時。
  3. 大量資料讀取考慮 CDbDataReader 或 Query Builder 避免實例化開銷。
  4. 關聯查詢使用 with() 預載入 (Eager Loading) 避免 N+1 問題:Post::model()->with('author', 'comments')->findAll()。
  5. 業務邏輯封裝在 AR 類別方法中 (如 $employee->promote()),Controller 保持輕量。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved