array_merge_recursive 并不安全:数字键会强制递归合并导致结构错乱;字符串键同名时无条件转数组,易引发类型错误;深层嵌套遇类型不一致会报错;需预处理参数并校验类型。

array_merge_recursive 看似安全,实则在处理含数字键或混合键的数组时容易引发隐性覆盖、结构错乱甚至逻辑错误。
数字键会被强制转为递归合并,而非追加
当两个数组都含有纯数字下标(如 [0 => 'a', 1 => 'b'] 和 [0 => 'x', 1 => 'y']),array_merge_recursive 不会像 array_merge 那样“后项追加到末尾”,而是把相同数字键的值自动包裹成数组:
结果变成 [0 => ['a', 'x'], 1 => ['b', 'y']] —— 这往往不是你想要的扁平化合并。
- 若原意是拼接列表,应改用
array_merge($a, $b) - 若需保留数字索引并避免嵌套,先用
array_values()重置键再合并
字符串键同名时强制递归,可能破坏数据类型
遇到相同字符串键(如 ['name' => 'Alice'] 和 ['name' => 'Bob']),函数会无视值类型,一律合并为数组:['name' => ['Alice', 'Bob']]。一旦后续代码假设 $data['name'] 是字符串,就会触发 Warning: Trying to access array offset on value of type string 或静默逻辑异常。
- 检查是否真需要递归行为;多数配置合并、表单数据合并场景其实要的是“后者覆盖前者”
- 可考虑用
array_replace_recursive(PHP 5.3+)替代,它对字符串键默认覆盖而非无条件递归
深层嵌套时易产生意外多层数组
若源数组中某键对应值已是数组(如 ['meta' => ['tags' => ['php']]]),而另一数组也有 'meta' 键且值也是数组,array_merge_recursive 会逐层钻入合并。但若其中一层值类型不一致(比如一个是字符串,一个是数组),就会报错或生成非预期结构。
- 合并前建议用
is_array()校验关键路径的值类型 - 对不确定结构的数据,优先使用明确控制逻辑的手写递归合并函数,或借助
json_encode/json_decode做浅拷贝后再处理
空数组或 null 值参与时行为易被忽略
传入 null 或非数组参数会直接触发警告(Warning: array_merge_recursive(): Argument #1 is not an array);传入空数组虽不报错,但可能掩盖上游数据缺失问题。
- 调用前统一过滤:用
is_array()+array_filter()预处理参数 - 避免直接传变量,改用
array_merge_recursive(...array_values(array_filter($arrays, 'is_array')))










