
本文介绍一种动态合并任意数量关联数组的方法,对相同键的子数组中 price 和 qty 字段执行数值累加,其余字段(如 name、category)保留最后一次出现的值,适用于商品汇总、库存合并等场景。
本文介绍一种动态合并任意数量关联数组的方法,对相同键的子数组中 price 和 qty 字段执行数值累加,其余字段(如 name、category)保留最后一次出现的值,适用于商品汇总、库存合并等场景。
在实际开发中,常需将多个结构一致的关联数组(如不同来源的商品数据)合并为一个统一数组,并对数值型字段(如 price、qty)按相同主键(如商品 ID)进行求和,而非简单覆盖或忽略。PHP 原生的 + 运算符或 array_merge() 无法满足此需求——它们仅做浅层键覆盖,不支持字段级智能聚合。
以下是一个健壮、可扩展的解决方案,支持任意数量输入数组(2 个或 15 个均可),使用 PHP 的可变参数语法 ...$arrays 实现动态接收,并通过双重循环完成精准合并:
<?php
function mergeArraysBySum(Array ...$arrays): array
{
if (empty($arrays)) {
return [];
}
// 以第一个数组为基准初始化结果
$result = $arrays[0];
// 遍历剩余所有数组
for ($i = 1; $i < count($arrays); $i++) {
foreach ($arrays[$i] as $key => $item) {
if (isset($result[$key])) {
// 合并时:price 和 qty 执行数值相加(自动类型转换)
$result[$key]['price'] = (float)$result[$key]['price'] + (float)$item['price'];
$result[$key]['qty'] = (int)$result[$key]['qty'] + (int)$item['qty'];
// 其他字段(name、category)取当前数组中的值(即“后写入优先”)
$result[$key]['name'] = $item['name'] ?? $result[$key]['name'];
$result[$key]['category'] = $item['category'] ?? $result[$key]['category'];
} else {
// 键不存在则直接插入
$result[$key] = $item;
}
}
}
return $result;
}
// 示例数据
$arr1 = [
51 => ['name' => 'p1', 'price' => '20', 'qty' => '10', 'category' => 'c1'],
3 => ['name' => 'p2', 'price' => '10.50', 'qty' => '3', 'category' => 'c2']
];
$arr2 = [
3 => ['name' => 'p3', 'price' => '23', 'qty' => '22', 'category' => 'c1'],
102 => ['name' => 'p4', 'price' => '10.50', 'qty' => '8', 'category' => 'c2']
];
$arr3 = [ // 可选:第三个数组演示扩展性
51 => ['name' => 'p1-upd', 'price' => '5', 'qty' => '2', 'category' => 'c1-pro'],
77 => ['name' => 'p5', 'price' => '15.99', 'qty' => '12', 'category' => 'c3']
];
// 调用示例(支持2个、3个或更多数组)
$merged = mergeArraysBySum($arr1, $arr2, $arr3);
print_r($merged);
?>✅ 关键特性说明:
- ✅ 动态参数支持:使用
Array ...$arrays接收任意数量数组,无需预定义参数个数; - ✅ 安全类型转换:显式
(float)和(int)强制转换,避免字符串拼接(如'10' + '20'→30,而非'1020'); - ✅ 字段策略清晰:
price/qty求和;name/category等非数值字段采用“后覆盖前”策略(符合示例预期); - ✅ 空数组防御:开头校验
empty($arrays),防止索引越界; - ✅ 返回明确:函数严格返回
array类型,便于链式调用或进一步处理。
⚠️ 注意事项:
- 输入数组必须是关联数组,且每个子数组需包含
price、qty等目标键,否则会触发Notice;建议生产环境增加isset()或array_key_exists()校验; - 若需自定义聚合字段(如新增
discount求和),只需在循环内扩展对应逻辑; - 如需“首次值优先”(而非最后值),将赋值语句改为
$result[$key]['name'] = $result[$key]['name'] ?? $item['name'];即可。
该方案简洁、高效、可维护,是处理多源业务数据聚合的理想实践。

















