
本文介绍如何在 yii2 中遍历获奖记录,关联查询对应用户和商品信息,并将结构化数据组装为统一的 json 响应数组,避免低效的 arrayhelper::merge 误用。
在构建 JSON API 时,常需将多个模型的数据聚合为扁平、语义清晰的响应结构。例如,展示“获奖榜单”时,每个条目需同时包含用户姓名(来自 User 模型)、奖品图片与标题(来自 Products 模型),而原始数据仅存于 Winners 表中。此时,不应使用 ArrayHelper::merge() 逐层覆盖合并对象——它适用于键值合并(如配置叠加),而非构建列表项;更关键的是,$data[] = [...] 才是向结果数组追加新条目的正确方式。
以下为推荐实现:
$winners = Winners::find()->limit(8)->all();
$data = []; // 显式初始化空数组,提升可读性与健壮性
foreach ($winners as $winner) {
// 关联查询用户(注意:findIdentity 仅接受主键,确保 $winner->user_id 非空且有效)
$user = User::findIdentity($winner->user_id);
if (!$user) {
continue; // 跳过用户不存在的脏数据,避免 Notice 错误
}
// 关联查询本地化商品(需确保 Products::localized() 正确实现语言作用域)
$product = Products::find()
->localized($lang)
->where(['coupon' => $winner->coupon])
->one();
if (!$product) {
continue; // 跳过商品未找到的情况
}
// 组装结构化条目:字段名语义明确,便于前端消费
$data[] = [
'id' => $winner->id,
'image' => $product->prize_image ?? '',
'user' => trim("{$user->firstname} {$user->lastname}"),
'title' => $product->win_title ?? '',
'coupon' => $winner->coupon,
'created_at' => $winner->created_at,
];
}
// 返回标准 JSON 响应(Yii2 控制器中通常直接 return $data;)
return $data;✅ 关键要点总结:
- 使用 $data[] = [...] 向数组末尾追加新元素,而非反复 ArrayHelper::merge() —— 后者在循环中会不断覆盖或嵌套,无法生成预期的列表结构;
- 务必对关联查询结果做存在性检查(if (!$user)),防止因外键不一致导致 PHP Notice 或 API 崩溃;
- 字段命名采用小写+下划线风格(如 prize_image),符合 Yii2 默认约定,也利于 JSON 兼容性;
- 若性能敏感(如 winners 数量增长),建议改用 JOIN 查询 + asArray() 一次性获取所有数据,避免 N+1 查询问题。
该方案简洁、健壮、符合 Yii2 最佳实践,可直接集成至 RESTful 控制器或数据服务层。










