array_merge() 对数字键数组强制从0开始连续重编号,字符串键则保留原键;混用+运算符或array_merge_recursive()会导致不重编号;需自定义起始编号时须组合array_values()与array_combine()。

array_merge() 本身就会重新编号——但只对纯数字键(即索引数组)生效,且是强制从 0 开始连续编号。如果你发现合并后没重编号,大概率是因为数组里混了字符串键,或者你误用了 + 运算符。
array_merge() 对索引数组的重编号行为是默认且不可关闭的
array_merge() 的设计逻辑很明确:
- 遇到纯数字键(如
[0=>'a', 1=>'b']或[5=>'x', 10=>'y']),一律丢弃原键,新数组从0开始连续编号; - 遇到字符串键(如
['id'=>1, 'name'=>'foo']),保留原键,不重编号; - 混合数组时,数字键部分被重编号,字符串键部分原样保留。
常见错误现象:
- 合并后还是
[5=>'x', 10=>'y']→ 实际上你用的是$a + $b,不是array_merge(); - 合并后出现
[0=>'a', 1=>'b', 0=>'x', 1=>'y']→ 你用了array_merge_recursive(),它不重编号数字键,只做递归合并。
示例:
立即学习“PHP免费学习笔记(深入)”;
$a = [5 => 'apple', 12 => 'banana']; $b = [0 => 'cherry', 1 => 'date']; $result = array_merge($a, $b); // 输出:[0=>'apple', 1=>'banana', 2=>'cherry', 3=>'date']
想要“保留原数字键”?别用 array_merge(),改用 + 运算符
+ 是 PHP 原生数组合并运算符,它按左优先、不重编号、不覆盖同键值的方式合并:
- 只有当左右数组存在完全相同的数字或字符串键时,左边的值才保留,右边被忽略;
- 它不会触碰任何键名,数字键照旧,字符串键照旧;
- 但它不保证顺序(PHP 7.4+ 保持插入顺序,但语义上仍是“左覆盖右”,不是“追加”)。
示例:
立即学习“PHP免费学习笔记(深入)”;
$a = [0 => 'a', 2 => 'c']; $b = [1 => 'b', 3 => 'd']; var_dump($a + $b); // 输出:[0=>'a', 2=>'c', 1=>'b', 3=>'d'] —— 键未重排,也未重编号
注意:这不是“合并后重编号”的方案,而是“绕过重编号”的替代手段。
真需要手动控制重编号起点?用 array_values() + array_merge() 组合
array_merge() 已经做了重编号,但如果你合并前的数组本身带非零起始索引(比如 [10=>'x', 11=>'y']),而你希望最终从 100 开始编号,就得自己干预:
- 先用
array_merge()合并 → 得到[0=>'x', 1=>'y', ...]; - 再用
array_values()确保是纯索引数组(其实array_merge()已保证这点); - 最后用
array_map()或循环 +array_combine()重映射键。
简单重编号为从 100 起:
$merged = array_merge($a, $b); $keys = range(100, 100 + count($merged) - 1); $result = array_combine($keys, array_values($merged));
但注意:这仅适用于小数组;大数组中频繁 array_combine() 有性能开销,且 array_combine() 要求键/值数量严格一致,否则返回 false。
重编号这件事看似简单,实际容易混淆的点在于:你以为在“控制重编号”,其实是在选函数——array_merge() 强制重编号,+ 完全不重编号,没有中间态。真正需要定制编号逻辑时,得自己写循环或用 array_values() + array_combine() 显式构造,而不是指望某个内置函数“参数化重编号”。



















