PHP中数组加号(+)是键名级并集运算,左数组优先、不重排键;array_merge()则重置数字键为连续索引,二者设计目标不同。

因为加号(+)在 PHP 中不是“拼接”操作,而是**键名级别的并集运算**——它只关心“某个键是否存在”,不关心数字键是否连续或是否该从 0 开始编号。
加号的本质是“左数组优先的键覆盖控制”
它逐个检查右数组的每个键:
- 如果这个键(无论数字还是字符串)在左数组中已存在,直接跳过右数组对应值
- 如果这个键在左数组中不存在,才把“键 + 值”原样加入结果
- 整个过程完全不触碰左数组原有的键结构,也不对任何键做重排、转换或递增处理
对比 array_merge() 就更清楚了
array_merge() 的设计目标是“把所有值按顺序收拢成一个新数组”,所以它必须抹掉原始数字键,统一用 0、1、2… 连续编号,确保索引可预测;而+的设计目标是“保留左侧语义结构,仅补充缺失项”,数字键本身就是语义的一部分(比如第 0 项是标题、第 5 项是发布时间),重编号反而会破坏逻辑。
数字键被当成普通键来对待
PHP 内部并不区分“这是索引数组”还是“这是关联数组”——它只看键的类型和值。当你写 [66 => 'a', 77 => 'b'],PHP 就记下两个键:整数 66 和整数 77。加号运算时,它只是查表:“66 在左数组里吗?在 → 不管右数组有没有 66;77 在左数组里吗?不在 → 把 77=>'b' 加进去”。没有“重新编号”这一步,因为根本没这个需求。
立即学习“PHP免费学习笔记(深入)”;
这种行为带来确定性,也带来限制
它保证了结果可预期:只要左数组不变,+ 右数组的结果就一定不变;但也要注意,如果右数组带了个左数组已有的数字键(比如左有 [0=>'x'],右有 [0=>'y', 2=>'z']),那 0=>'y' 会被静默丢弃,2=>'z' 才会补上——这不是 bug,是设计使然。



















