Yii 的 ActiveRecord 查詢預設回傳物件,但在 API 開發、資料匯出或模板渲染時,常需轉為陣列或 JSON 格式。本文整理各種查詢情境下的轉換方法。
使用 find()、findByPk()、findByAttributes() 取得單一模型時:
<?php // 查詢單筆 $post = Post::model()->find($condition, $params); $post = Post::model()->findByPk($postID, $condition, $params); $post = Post::model()->findByAttributes($attributes, $condition, $params); // 直接取得屬性陣列(含關聯資料) $array = $post->attributes; // 若需包含關聯模型 $array = $post->getAttributes(null, true); // true = 遞迴包含關聯 ?>
使用 findAll() 取得模型陣列時:
<?php
$posts = Post::model()->findAll($condition, $params);
// 方法 1:陣列對應(推薦)
$arrays = array_map(function($model) {
return $model->attributes;
}, $posts);
// 方法 2:foreach 迴圈
$arrays = array();
foreach ($posts as $post) {
$arrays[] = $post->attributes;
}
// 方法 3:Yii 1.1.14+ 內建方法
$arrays = $posts->getAttributes(); // 僅適用於 CModel 陣列包裝器
?>
繞過 ActiveRecord,直接使用 DAO 或 Query Builder:
<?php
// CDbCommand::queryAll() 直接回傳陣列
$rows = Yii::app()->db->createCommand()
->select('id, title, content')
->from('post')
->where('status=1')
->queryAll();
// 使用 Query Builder (Yii 1.1.6+)
$rows = Yii::app()->db->createCommand()
->from('post')
->where(array('in', 'id', array(1,2,3)))
->queryAll();
?>
JSON 輸出最佳實務
<?php
// API 回傳 JSON
header('Content-Type: application/json; charset=UTF-8');
$posts = Post::model()->findAll('status=1');
$data = array();
foreach ($posts as $post) {
$data[] = $post->attributes;
}
echo json_encode(array(
'success' => true,
'data' => $data,
'total' => count($data)
), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
?>
常見問題與解決方案
| 問題 | 原因 | 解決 |
|---|---|---|
| 關聯資料未包含 | attributes 預設不含關聯 | 使用 getAttributes(null, true) 或手動合併 |
| 日期欄位格式不一致 | 資料庫 DATETIME 直接輸出 | 模型加入 afterFind() 格式化或 API 層統一處理 |
| 大量資料記憶體不足 | findAll() 一次載入所有模型 | 使用 CDbDataReader 分批處理或 queryAll() |
| 遞迴關聯導致循環參考 | 雙向關聯(如 Post <-> Author) | 指定需包含的關聯名稱,避免 true 參數 |
Yii 2.0 中 ActiveRecord 預設即支援陣列轉換:
<?php
// Yii 2.0
$posts = Post::find()->where(['status' => 1])->all();
$arrays = array_map(function($model) {
return $model->toArray(); // 或 $model->attributes
}, $posts);
// 或直接 asArray()
$arrays = Post::find()->asArray()->where(['status' => 1])->all();
?>
掌握物件轉陣列技巧,能靈活應對 API 開發、資料匯出、搜尋引擎索引等多樣化需求,是 Yii 開發者必備技能。