
本文介绍如何编写一个支持多层嵌套的递归数组合并函数,使源数组中已存在的键值优先保留,而目标数组中新增的键值(包括深层嵌套)被自动补全,适用于配置合并、默认值填充等场景。
本文介绍如何编写一个支持多层嵌套的递归数组合并函数,使源数组中已存在的键值优先保留,而目标数组中新增的键值(包括深层嵌套)被自动补全,适用于配置合并、默认值填充等场景。
在 PHP 开发中,array_merge() 是常用数组合并工具,但它仅执行浅层合并——遇到同名数组键时直接覆盖,而非递归合并子数组。当需要“以第一个数组为基准,仅用第二个数组补充缺失的键(含多级嵌套)”时,就必须自定义递归逻辑。
以下是一个简洁、健壮且可扩展的递归合并函数 recursive_merge_fill(),它严格遵循「保留 $array_1 中所有已有值,仅用 $array_2 填充 $array_1 中不存在的键(包括深层键)」的原则:
function recursive_merge_fill($array_1, $array_2) {
$merged = $array_1; // 初始化结果为源数组(保留所有现有数据)
foreach ($array_2 as $key => $value) {
// 若 $array_1 中无此键,或该键对应值非数组(即不可递归),则直接赋值
if (!array_key_exists($key, $array_1) || !is_array($array_1[$key]) || !is_array($value)) {
$merged[$key] = $value;
} else {
// 两者均为数组 → 递归处理子层级
$merged[$key] = recursive_merge_fill($array_1[$key], $value);
}
}
return $merged;
}✅ 使用示例:
$array_1 = [
'array_key' => [
'array_key_1' => 1,
'array_key_2' => 2,
'array_key_3' => 3,
],
];
$array_2 = [
'array_key' => [
'array_key_1' => null,
'array_key_2' => null,
'array_key_3' => null,
'array_key_4' => null,
'array_key_5' => null,
],
];
$result = recursive_merge_fill($array_1, $array_2);
print_r($result);
// 输出:
// Array (
// [array_key] => Array (
// [array_key_1] => 1
// [array_key_2] => 2
// [array_key_3] => 3
// [array_key_4] => null
// [array_key_5] => null
// )
// )⚠️ 注意事项与最佳实践:
立即学习“PHP免费学习笔记(深入)”;
-
键存在性判断优于
empty():原问题代码使用empty($array_1[$key])易误判0、false、''等合法值为“空”。应改用array_key_exists()或isset()配合类型校验。 -
避免无限递归:若输入数组存在循环引用(如
$a = [&$a]),本函数将触发栈溢出。生产环境建议配合spl_object_hash()或引用计数检测(需额外封装),或明确禁止传入引用环。 -
语义清晰性:该函数不是
array_merge_recursive()的替代品——后者会将同键值“并列追加”,而本函数是「优先源值 + 按需填充」,更贴近“默认配置 + 用户覆盖”的典型需求。 - 扩展建议:如需支持更多策略(如强制覆盖、深度去重、回调过滤),可将合并逻辑抽象为策略接口,通过闭包参数注入行为。
掌握此函数,你便拥有了一个轻量、可靠、符合直觉的递归数组填充工具,大幅提升配置管理、API 响应构造及模板数据组装的开发效率。



















