
本文介绍如何将多个 JSON 字段解析后的关联键值对,按键聚合为唯一值数组——即把形如 [[2=>3], [3=>5], [2=>4], [3=>5]] 的二维数组,高效转换为 [2 => [3,4], 3 => [5]] 的结构。
本文介绍如何将多个 json 字段解析后的关联键值对,按键聚合为唯一值数组——即把形如 `[[2=>3], [3=>5], [2=>4], [3=>5]]` 的二维数组,高效转换为 `[2 => [3,4], 3 => [5]]` 的结构。
在实际开发中(尤其是处理 MySQL 中存储的 JSON 字段时),常遇到多条记录各自携带结构相似的 JSON 数据,例如:
{"2": "3", "3": "5"}
{"2": "4", "3": "5"}
{"2": "3", "4": "7"}
目标是将所有记录中相同键(如 "2")对应的所有值收集起来,并自动去重,最终形成以原始 JSON 键为索引、值为唯一数字/字符串数组的新结构。
核心思路:键驱动聚合 + 值去重
关键在于跳过中间的“扁平化二维数组”步骤(如 $optionValuesArrayContainer),直接在解析 JSON 时按键归集。这样既节省内存,又避免冗余中间结构。
以下是推荐的优化实现:
$result = [];
foreach ($item_options as $row) {
// 安全解码 JSON,忽略空或无效数据
$sons = json_decode($row['option_sons'], true);
if (!is_array($sons)) {
continue;
}
foreach ($sons as $key => $value) {
// 确保键存在且值非 null/undefined
if (!isset($result[$key])) {
$result[$key] = [];
}
// 追加当前值并自动去重(使用 array_unique 后重新索引)
$result[$key][] = $value;
}
}
// 对每个子数组执行去重并重置数字索引
foreach ($result as $k => $values) {
$result[$k] = array_values(array_unique($values));
}
print_r($result);
// 输出示例:
// Array (
// [2] => Array([0] => 3, [1] => 4)
// [3] => Array([0] => 5)
// [4] => Array([0] => 7)
// )
⚠️ 注意事项与最佳实践
- 类型一致性:json_decode(..., true) 必须启用关联数组模式,否则对象属性无法用 $sons[$key] 访问;
- 键类型安全:MySQL JSON 中的键始终为字符串(如 "2"),PHP 数组会自动转换为整型键(2),但若需严格保留字符串键,请显式使用 (string)$key;
- 性能优化:避免在内层循环反复调用 array_merge() 和 array_unique();先累积再统一去重更高效;
- 错误防御:添加 json_last_error() === JSON_ERROR_NONE 检查,防止非法 JSON 导致静默失败;
- 扩展性考虑:如需保持插入顺序或支持嵌套结构,可改用 SplObjectStorage 或自定义归集逻辑。
该方案简洁、健壮,适用于电商 SKU 属性聚合、多变体选项去重等典型场景,无需依赖额外扩展,纯原生 PHP 即可完成。










