
本文介绍如何编写一个支持多层嵌套的递归数组合并函数,使源数组中已存在的键值优先保留,目标数组中新增的键值被补充进来,适用于配置合并、数据补全等场景。
本文介绍如何编写一个支持多层嵌套的递归数组合并函数,使源数组中已存在的键值优先保留,目标数组中新增的键值被补充进来,适用于配置合并、数据补全等场景。
在 PHP 开发中,array_merge() 是常用的数据合并工具,但它仅执行扁平化合并——遇到同名数组键时直接覆盖,而非递归合并其内部元素。当需要“以第一个数组为基准,仅用第二个数组补充缺失的键(包括深层嵌套)”时,就必须自定义递归逻辑。
以下是一个简洁、健壮且可复用的递归合并函数:
function array_merge_recursive_fill($base, $overlay) {
$result = $base; // 以 base 为基准,只补充 overlay 中 base 缺失的部分
foreach ($overlay as $key => $value) {
// 若 base 中不存在该键,或对应值非数组(类型不匹配),则直接覆盖
if (!isset($base[$key]) || !is_array($base[$key]) || !is_array($value)) {
$result[$key] = $value;
} else {
// 递归合并子数组
$result[$key] = array_merge_recursive_fill($base[$key], $value);
}
}
return $result;
}
✅ 使用示例:
$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 = array_merge_recursive_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
// )
// )
⚠️ 注意事项:
-
类型安全优先:当
$base[$key]和$overlay[$key]类型不一致(如一者为数组、另一者为字符串/null),函数会直接用$overlay[$key]覆盖——这是有意设计,避免隐式类型转换引发歧义。 -
不处理循环引用:若输入数组存在自我引用(如
&$a[0] = &$a),该函数可能陷入无限递归。生产环境如需支持,应引入引用检测(例如使用spl_object_hash()或debug_backtrace()辅助判重),但会显著增加复杂度;建议前置校验或约定输入为纯数据结构。 -
与原生函数区分命名:本函数命名为
array_merge_recursive_fill,强调其语义是「填充缺失键」,而非array_merge_recursive(后者是 PHP 内置函数,行为为 键值追加,同名键会形成数组而非覆盖)。
? 进阶提示:如需更灵活的策略(例如“仅填充 null 值”、“跳过特定键”或“支持回调定制合并逻辑”),可将函数升级为接受第三个参数 $options 数组,实现可配置化合并器——这正是现代 PHP 配置管理器(如 Symfony Config)的核心思想。
掌握该模式,你就能高效构建可扩展的数据合并层,让配置继承、API 响应补全、模板变量兜底等场景更加清晰可控。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











