
本文介绍如何将包含多币种价格的扁平化商品数组,转换为每种货币单独成行的规范化结构,使用嵌套循环与数组追加技巧解决数据覆盖问题。
本文介绍如何将包含多币种价格的扁平化商品数组,转换为每种货币单独成行的规范化结构,使用嵌套循环与数组追加技巧解决数据覆盖问题。
在实际开发中(如电商后台、多币种报表生成或API数据标准化),我们常遇到类似需求:原始数据以“一行一商品、多列多币种”的宽表形式存储,但下游系统要求“一行一币种、一商品多行”的长表格式。上述问题正是典型场景——需将每个商品的 price_in_dollar、price_in_euro 等字段拆解为独立对象,并保留 toy_id 和 toy_name(映射为 toy)作为关联维度。
核心难点在于避免数据覆盖:原代码中 $cars 被反复赋值而非追加,导致仅保留最后一次循环结果。正确做法是为每个源数据项预先构建共享基础字段,再对每个价格字段动态生成新行并推入结果数组。
以下是推荐的实现方案(PHP):
$cars = []; // 初始化空结果数组
foreach ($data as $r) {
// 提取每件玩具的公共字段(固定不变)
$base = [
'toy' => $r['toy_name'],
'toy_id' => $r['toy_id']
];
// 遍历所有键值对,筛选出价格字段(排除 toy_name 和 toy_id)
foreach ($r as $key => $value) {
if (in_array($key, ['toy_name', 'toy_id'])) {
continue; // 跳过非价格字段
}
// 构建单条价格记录:复用 base + 动态 price 字段
$record = $base + [
'rate' => $value,
'slug' => $key
];
$cars[] = $record; // ✅ 关键:使用 [] 追加,而非覆盖
}
}✅ 关键要点说明:
立即学习“PHP免费学习笔记(深入)”;
- 使用 $base 数组预存不变字段,避免重复书写;
- 利用 + 数组合并操作(而非引用或赋值)确保每次生成全新记录;
- in_array() 比多重 if/else 更清晰易维护,可轻松扩展需忽略的字段;
- $cars[] = $record 是核心——它将新行追加到数组末尾,而非覆盖同一变量。
⚠️ 注意事项:
- 若原始数据中存在非价格字段(如 created_at、category),需将其加入 in_array() 的排除列表;
- 若需对 slug 值做标准化处理(如去除 price_in_ 前缀),可在赋值前添加 str_replace('price_in_', '', $key);
- 大数据量下建议启用内存优化(如 unset($r) 或使用生成器),但本例中常规循环已足够高效。
该方法逻辑清晰、扩展性强,适用于任意数量的价格字段和商品条目,是数据形态转换(Wide → Long)的经典实践。



















