
本文介绍如何在 PHP 中对商品数据数组按 color 分组,并为每个颜色下的 size 项构建灵活的嵌套结构:当某颜色仅有一种尺寸时,直接以字符串和 count 字段平铺输出;含多种尺寸时,则生成 size 数组子对象。
本文介绍如何在 php 中对商品数据数组按 `color` 分组,并为每个颜色下的 `size` 项构建灵活的嵌套结构:当某颜色仅有一种尺寸时,直接以字符串和 `count` 字段平铺输出;含多种尺寸时,则生成 `size` 数组子对象。
在电商或库存管理类应用中,常需将扁平的商品属性数组(如 color、size、count)聚合成更具语义的层级结构,以适配前端渲染或 API 响应规范。本教程提供一种清晰、可维护的 PHP 实现方案,支持动态深度结构——即根据每种颜色关联的尺寸数量,自动选择扁平字段或嵌套数组格式。
核心思路:两阶段处理
-
归集阶段:以
color为键,构建二维关联数组$colors[$color][$size] = $count; -
结构化阶段:遍历归集结果,判断每种颜色的尺寸数量,决定
size字段是单值字符串 +count,还是含多个{value, count}对象的数组。
完整实现代码
<?php
$array = [
['color' => '#000000', 'size' => 'L', 'count' => 2],
['color' => '#000000', 'size' => 'XL', 'count' => 1],
['color' => '#ffffff', 'size' => 'L', 'count' => 2],
['color' => '#ffffff', 'size' => 'XL', 'count' => 1],
['color' => '#ff0000', 'size' => 'L', 'count' => 1]
];
// 阶段一:按 color → size 归集 count
$colors = [];
foreach ($array as $row) {
$colors[$row['color']][$row['size']] = $row['count'];
}
// 阶段二:构建目标结构(支持单尺寸扁平化 & 多尺寸嵌套)
$output = [];
foreach ($colors as $color => $sizes) {
$sizeEntries = [];
foreach ($sizes as $size => $count) {
$sizeEntries[] = ['value' => $size, 'count' => $count];
}
if (count($sizeEntries) === 1) {
// 单尺寸:平铺为 color + size(string) + count
$output[] = [
'color' => $color,
'size' => $sizeEntries[0]['value'],
'count' => $sizeEntries[0]['count']
];
} else {
// 多尺寸:size 为对象数组
$output[] = [
'color' => $color,
'size' => $sizeEntries
];
}
}
// 输出标准化 JSON(带缩进,便于调试)
echo json_encode($output, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
?>输出结果(符合题目要求)
[
{
"color": "#000000",
"size": [
{
"value": "L",
"count": 2
},
{
"value": "XL",
"count": 1
}
]
},
{
"color": "#ffffff",
"size": [
{
"value": "L",
"count": 2
},
{
"value": "XL",
"count": 1
}
]
},
{
"color": "#ff0000",
"size": "L",
"count": 1
}
]注意事项与最佳实践
- ✅ 避免
extract():原答案中使用extract()虽简洁,但存在变量污染与安全风险(尤其在不可信数据场景),本实现改用显式键访问,更健壮、易调试; - ✅ 无重复校验假设:代码默认输入中不存在相同
color+size的重复项;若存在,后出现的count将覆盖前者——如需累加,可将$colors[$row['color']][$row['size']] += $row['count'];; - ✅ 可封装为函数:建议将逻辑封装为
groupProductsByColor(array $data): array,提升复用性与测试友好度; - ⚠️ 字符大小写敏感:示例中
"XL"与"Xl"视为不同尺寸,如需忽略大小写,可在归集前统一strtolower($row['size'])。
该方案兼顾可读性、扩展性与生产安全性,适用于中等规模数据聚合场景。

















