
本文介绍在 yii2 框架中,如何通过循环关联查询将 winners 模型与对应 user、product 数据结构化合并,生成符合 api 规范的嵌套数组,并最终输出为 json 响应。
在构建 JSON API 时,常需将主模型(如 Winners)与其关联的用户信息(User)和商品信息(Products)整合为统一的数据结构。直接使用 ArrayHelper::merge() 并不可取——它适用于扁平化合并键值对,而此处目标是按条目聚合多维度对象属性,形成清晰、可序列化的数组列表。
推荐做法是:先获取获奖记录集合,再逐条查询关联数据,并手动构造结构化子数组。示例如下:
$winners = Winners::find()->limit(8)->all();
$data = [];
foreach ($winners as $winner) {
// 查询用户(注意:findIdentity 需传入有效 ID,建议增加空值校验)
$user = $winner->user_id ? User::findIdentity($winner->user_id) : null;
// 查询本地化商品(确保 $lang 已定义且 $winner->coupon 非空)
$product = $winner->coupon
? Products::find()
->localized($lang)
->where(['coupon' => $winner->coupon])
->one()
: null;
// 构建每条获奖记录的标准化结构
$data[] = [
'id' => $winner->id,
'user_name' => $user ? ($user->firstname . ' ' . $user->lastname) : 'Unknown',
'user_email' => $user ? $user->email : null,
'prize_image'=> $product ? $product->prize_image : null,
'win_title' => $product ? $product->win_title : 'No prize',
'coupon' => $winner->coupon,
'created_at' => $winner->created_at,
];
}
// 返回 JSON 响应(Yii2 推荐方式)
return $this->asJson($data);✅ 关键优势:
- 避免 ArrayHelper::merge() 的语义误用(该方法用于合并同层级键值,不适用于构建对象列表);
- 显式控制字段命名与默认值,提升 API 可读性与健壮性;
- 支持空值安全处理(如用户/商品不存在时提供 fallback);
- 兼容 Yii2 的 asJson() 自动设置 Content-Type 与 JSON 编码。
⚠️ 注意事项:
- 若数据量较大(如 winners > 100 条),应改用 JOIN 查询 + with() 预加载优化性能,避免 N+1 查询;
- User::findIdentity() 仅支持主键查找,若 user_id 非主键,请改用 User::findOne($winner->user_id);
- localized() 是自定义作用域,需确保其已在 Products 模型中正确定义;
- 生产环境务必对 $lang 和 $winner->coupon 做合法性校验,防止 SQL 注入或查询异常。
最终,该方案输出的是标准 PHP 索引数组,可直接由 Yii2 序列化为规范 JSON,满足现代前端或第三方系统集成需求。










