array_merge() 会重置所有数字键并从0开始连续编号,因为PHP将纯数字键视为顺序列表;只要任一输入数组含整数键(如0、1、5),即触发重编号,字符串键则保留不变。

因为 array_merge() 的设计逻辑就是重置所有数字键——只要数组里存在整数索引(哪怕只有一个),它就会把整个结果数组的数字键全部丢弃,从 0 开始连续重新编号。
为什么这么做?
PHP 将“纯数字键”视为**顺序列表**(类似 C 语言数组),不强调键名本身的意义,只关心值的排列顺序。所以 array_merge() 把多个这样的列表“拼接”起来后,自然要生成一套新的、连续的下标,确保索引无空洞、可安全遍历。
这不是 bug,是明确的行为规范:数字键代表位置,不是标识符;一旦合并,位置关系就变了,旧编号失去意义。
什么情况会触发重编号?
- 任意输入数组中含至少一个整数键(如
[0=>'a', 2=>'b']或[1=>'x']) - 即使只传一个数字索引数组,也会重编号(
array_merge([5=>'hello'])→[0=>'hello']) - 混用字符串键和数字键时,仅数字键部分被重排,字符串键照常保留(如示例中
'color'和'shape'不变)
不想重编号?换方法
若你依赖原始数字键(比如用 1、3、100 做特殊标记),不能用 array_merge()。可用:
立即学习“PHP免费学习笔记(深入)”;
-
+运算符:保留左侧数组所有键,右侧同名键直接忽略($a + $b) -
array_replace():字符串键覆盖,数字键按位置替换(不重排,但只处理顶层) -
手动循环合并:用
foreach显式赋值,完全控制键行为
一个小提醒
别误以为“键是字符串数字”(如 '1'、'007')也算数字键——它们是字符串键,array_merge() 不会动它们。真正触发重编号的,只有 int 类型的键,比如 1、0、200。



















