array_walk_recursive() 不能合并数组,因其仅遍历并修改多维数组的叶子节点值,不改变结构、无法访问父键、无源/目标数组概念;应使用 array_merge_recursive() 或自定义递归函数实现合并。

PHP 8.0 中 array_walk_recursive() 本身**不用于合并数组**,它只用来遍历并修改多维数组的**叶子节点值**。想合并多维数组(比如把多个同结构数组递归合并),应该用 array_merge_recursive() 或自定义递归合并函数。
为什么 array_walk_recursive 不能合并数组
array_walk_recursive() 的作用是:对数组中所有**标量值(string/int/float/bool/null)** 执行回调,跳过子数组本身。它不改变数组结构,也不能访问父键、无法决定“如何合并”,更不能把两个数组“合在一起”。它的参数只有当前值、键、可选引用数组,没有“源数组”或“目标数组”的概念。
正确做法:用 array_merge_recursive 合并多维数组
这是 PHP 内置的、专为递归合并设计的函数:
- 相同字符串键的值会被“合并成数组”,而不是覆盖
- 数字键则直接追加(不递归)
- 支持任意数量参数(PHP 7.4+ 支持展开,PHP 8.0 完全兼容)
示例:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
$arr1 = ['a' => 1, 'b' => ['x' => 10]]; $arr2 = ['a' => 2, 'b' => ['y' => 20]]; $result = array_merge_recursive($arr1, $arr2); // 结果:['a' => [1, 2], 'b' => ['x' => 10, 'y' => 20]]
需要深度覆盖合并?写个自定义递归函数
如果希望相同键时“后数组覆盖前数组”(而非合并成数组),就要自己写递归逻辑:
function array_replace_recursive(array $base, array ...$replacements): array
{
foreach ($replacements as $repl) {
foreach ($repl as $key => $value) {
if (is_array($value) && isset($base[$key]) && is_array($base[$key])) {
$base[$key] = array_replace_recursive($base[$key], $value);
} else {
$base[$key] = $value;
}
}
}
return $base;
}
<p>// 使用
$arr1 = ['user' => ['name' => 'Alice', 'age' => 30]];
$arr2 = ['user' => ['age' => 31, 'city' => 'Beijing']];
$result = array_replace_recursive($arr1, $arr2);
// 结果:['user' => ['name' => 'Alice', 'age' => 31, 'city' => 'Beijing']]真要用 array_walk_recursive?只能做“统一处理”,不是合并
比如你想把所有字符串值转大写、或全部加前缀,可以用它:
$data = ['name' => 'alice', 'profile' => ['city' => 'shanghai', 'tags' => ['php', 'web']]];
<p>array_walk_recursive($data, function (&$item) {
if (is_string($item)) {
$item = strtoupper($item);
}
});
// $data 变成:['name' => 'ALICE', 'profile' => ['city' => 'SHANGHAI', 'tags' => ['PHP', 'WEB']]]注意:这不会新增键、不会合并结构、也不会处理数组本身 —— 它只是“就地修改叶子值”。


















