
本文介绍在 yii2 框架中,如何遍历获奖记录并关联查询用户和商品信息,最终结构化组装为统一数组用于 json api 输出,避免低效的多次 arrayhelper::merge 调用。
在构建 JSON API 时,常需将多个模型(如 Winners、User、Products)的数据聚合为扁平、语义清晰的响应结构。原始方案中反复调用 ArrayHelper::merge() 不仅逻辑冗余,且每次覆盖 $result 变量,导致仅保留最后一次合并结果,无法实现完整数据集组装。
更合理的方式是主动构造目标结构:遍历获奖者列表,逐条获取关联的用户与商品对象,并将所需字段提取后以关联数组形式追加至 $data 数组中。PHP 的数组推入语法 $data[] = [...] 是最简洁、高效的选择:
$winners = Winners::find()->limit(8)->all();
$data = []; // 显式初始化,提升可读性与健壮性
foreach ($winners as $winner) {
// 关联查询用户(注意:findIdentity 仅支持主键查找,若 user_id 非主键请改用 User::findOne($winner->user_id))
$user = User::findIdentity($winner->user_id);
// 关联查询本地化商品(确保 localized() 行为已正确定义于 Products 查询类中)
$product = Products::find()
->localized($lang)
->where(['coupon' => $winner->coupon])
->one();
// 安全提取字段:建议添加空值检查,防止 500 错误
if ($user && $product) {
$data[] = [
'image' => $product->prize_image ?? '',
'user' => trim("{$user->firstname} {$user->lastname}"),
'title' => $product->win_title ?? '',
'coupon' => $winner->coupon, // 可选:保留原始获奖凭证
];
}
}
// 返回标准 JSON 响应(Yii2 RESTful 风格)
return $data;✅ 关键优化点说明:
- 避免无意义合并:ArrayHelper::merge() 适用于深度合并配置数组,而非构建新结构;此处直接构造关联数组更直观、可控。
- 显式初始化 $data = []:防止未定义变量警告,符合 PSR-12 编码规范。
- 增加空值防护:$user && $product 判断可避免因关联数据缺失导致的 Trying to get property of non-object 异常。
- 字段命名语义化:如 'user' 合并为全名字符串,而非嵌套对象,更贴合前端消费习惯。
? 进阶建议:
- 若性能敏感,可改用 JOIN 查询一次性获取三表关联数据(需确保数据库关系建模合理);
- 对于多语言商品,确认 localized($lang) 方法已正确实现 andWhere() 或 joinWith() 逻辑;
- 在控制器中返回前,可使用 Json::encode() 显式编码(Yii2 默认 JSON 响应会自动处理,但调试时显式调用更可控)。
最终输出的 $data 是一个索引数组,每个元素均为含 image、user、title 等键的标准关联数组,可直接被 Yii2 的 Response 组件序列化为高质量 JSON API 响应。










