
本文介绍如何在 php 中对具有相同 id 的多维数组元素进行智能合并,尤其适用于聚合多个 providerdetails 数据的场景,涵盖字段覆盖策略、数组去重、嵌套结构合并等核心技巧。
本文介绍如何在 php 中对具有相同 id 的多维数组元素进行智能合并,尤其适用于聚合多个 providerdetails 数据的场景,涵盖字段覆盖策略、数组去重、嵌套结构合并等核心技巧。
在实际开发中,我们常遇到结构相似但来源不同的多维数组数据(例如来自不同 API 响应或数据库查询),其中部分记录拥有相同的业务主键(如 "id": "22"),但 providerDetails 内容各异。此时,简单使用 array_unique($arr, SORT_REGULAR) 并不能满足需求——它仅能去除完全相同的数组项,而无法实现“按 id 分组 + 深度合并字段”的逻辑。
✅ 正确做法是:以 id 为分组键,对同 id 的所有条目执行字段级合并。关键原则包括:
- 基础字段(如 name, is_current)通常保留首个出现的值(或按业务规则取优先级);
- providerDetails 需深度合并:标量字段可覆盖/跳过,数组类字段(如 providerService, locationService, provider_rating)应去重后合并;
- 避免简单 + 或 array_merge(),因其会丢失键名或覆盖嵌套结构。
以下是一个健壮、可复用的合并函数示例:
<?php
function mergeById(array $items, string $idKey = 'id'): array {
$merged = [];
foreach ($items as $item) {
$id = $item[$idKey] ?? null;
if ($id === null) continue;
if (!isset($merged[$id])) {
// 首次出现:完整保存基础结构
$merged[$id] = $item;
// 初始化 providerDetails 合并容器(若存在)
if (isset($item['providerDetails']) && is_array($item['providerDetails'])) {
$merged[$id]['providerDetails'] = $item['providerDetails'];
}
continue;
}
// 合并 providerDetails(深度合并)
if (isset($item['providerDetails']) && is_array($item['providerDetails'])) {
$target = &$merged[$id]['providerDetails'];
$source = $item['providerDetails'];
// 合并字符串/数字字段:保留首次值(可按需改为覆盖)
foreach (['id', 'name', 'email', 'phone_number', 'address', 'additional_info', 'telehealth', 'speaking'] as $field) {
if (isset($source[$field]) && !isset($target[$field])) {
$target[$field] = $source[$field];
}
}
// 合并布尔/开关字段(accepts_*):逻辑 OR(接受任一为 true)
foreach (['accepts_medicaid', 'accepts_private_pay'] as $flag) {
if (isset($source[$flag]) && $source[$flag] == '1') {
$target[$flag] = '1';
}
}
// 合并数组字段:去重后追加
foreach (['providerService', 'locationService'] as $listKey) {
if (isset($source[$listKey]) && is_array($source[$listKey])) {
$target[$listKey] = array_values(
array_unique(
array_merge($target[$listKey] ?? [], $source[$listKey]),
SORT_REGULAR
)
);
}
}
// 合并 provider_rating(保留全部对象,不判重)
if (isset($source['provider_rating']) && is_array($source['provider_rating'])) {
$target['provider_rating'] = array_merge(
$target['provider_rating'] ?? [],
$source['provider_rating']
);
}
// provider_avgrating 取平均或保留最大?此处示例:合并后去重,再取首个(业务可调)
if (isset($source['provider_avgrating']) && is_array($source['provider_avgrating'])) {
$target['provider_avgrating'] = array_values(
array_unique(
array_merge($target['provider_avgrating'] ?? [], $source['provider_avgrating']),
SORT_REGULAR
)
);
}
}
}
return array_values($merged);
}
// 使用示例
$data = json_decode($jsonString, true); // 假设 $jsonString 包含原始 JSON 数组
$mergedData = mergeById($data);
echo json_encode($mergedData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>⚠️ 重要注意事项:
立即学习“PHP免费学习笔记(深入)”;
- array_unique(..., SORT_REGULAR) 仅适用于扁平数组或完全一致的嵌套结构,对本例中 id 相同但 providerDetails 不同的场景无效;
- 合并策略需严格对齐业务语义:例如 provider_rating 是累加评论,不可去重;而 providerService 是服务 ID 列表,必须去重;
- 若需更高性能(大数据量),建议预构建索引或使用生成器流式处理;
- 生产环境务必添加类型校验与异常兜底(如 isset()、is_array()),避免 Notice 级错误。
总结:多维数组按 ID 合并不是简单的去重问题,而是需结合业务逻辑的结构化归并操作。掌握自定义合并函数的设计方法,比依赖单一内置函数更能保障数据一致性与可维护性。



















