运算符实现左侧优先联合,保留左数组键值不被右数组覆盖;对字符串键跳过同名项,数字键保留原索引;仅支持数组类型,不递归合并嵌套结构。

用 + 运算符保留左侧数组的键和值
当你需要“合并但不覆盖旧值”,核心是让已有键名的值不被右侧数组替换——+ 运算符正是为此设计的。它不是“追加”,而是“左侧优先联合”:遇到相同字符串键或数字键,直接跳过右侧对应项。
常见错误现象:array_merge($a, $b) 会用 $b 的值覆盖 $a 中同名字符串键;而 $a + $b 则始终保留 $a 的值,哪怕 $b 有同名键。
$a = ['id' => 1, 'name' => 'Alice']; $b = ['name' => 'Bob', 'email' => 'b@x.com'];-
$result = $a + $b;→['id' => 1, 'name' => 'Alice', 'email' => 'b@x.com'] - 注意:
$b的'name'被完全忽略,不会报错也不会警告
数字键行为差异:+ 保留原索引,array_merge 重排
数字键(包括隐式整数键)在 + 和 array_merge() 下表现完全不同。如果你依赖原始索引(比如题号、ID、顺序标识),用错函数会导致 key 错乱甚至数据错位。
例如:$a = [0 => 'Q1', 1 => 'Q2']; $b = [0 => 'Q3', 1 => 'Q4'];
立即学习“PHP免费学习笔记(深入)”;
-
$a + $b→[0 => 'Q1', 1 => 'Q2']($b的0和1因已存在被丢弃) -
array_merge($a, $b)→[0 => 'Q1', 1 => 'Q2', 2 => 'Q3', 3 => 'Q4'](全部重索引) - 若你本意是“把
$b当作独立题块补在后面”,且题号是 key(如[25 => 'A', 26 => 'B']),那+才能真正保留语义
空数组或非数组参与 + 运算时会报错
+ 是数组联合运算符,只接受两个数组。如果其中一个是 null、false 或字符串,PHP 会抛出 Fatal error: Unsupported operand types。
使用场景多见于表单处理或 API 响应合并,比如某字段可能未提交导致变量未定义:
- 错误写法:
$data = $_POST['section_a'] + $_POST['section_b'];(若任一为null就崩) - 安全写法:
$a = (array)($_POST['section_a'] ?? []); $b = (array)($_POST['section_b'] ?? []); $data = $a + $b; - 更稳妥:统一初始化为数组,避免类型强制转换意外(如
(array)"foo"得到[0 => "foo"])
嵌套数组需递归处理,+ 不适用
+ 只做一层联合,遇到值为数组的键,不会深入合并子结构。比如 $a['meta'] = ['lang' => 'zh']; $b['meta'] = ['theme' => 'dark'];,$a + $b 中 'meta' 仍是 $a['meta'],$b['meta'] 被丢弃。
此时必须换策略:
- 若要保留所有子键,用
array_merge_recursive(),但注意它对数字键仍会追加,且字符串键会变成数组(如['meta' => ['lang' => 'zh', 'theme' => 'dark']]) - 若要精确控制嵌套逻辑(比如只合并特定层级、跳过某些键),得手写
foreach+ 递归判断,不能依赖单一内置函数 - PHP 8.1+ 可考虑
array_key_first()/array_key_last()辅助定位,但不解决合并本质问题
真正容易被忽略的是:你以为的“保留旧值”只在单层关联数组下成立;一旦结构变深,+ 就失效了,而且不会报错,只是静默丢数据。



















