PHP索引数组直接赋值$new = $old即可浅拷贝,无需额外函数;若需重排键名则用array_values(),避免array_merge()在混合键时的错乱问题。

直接赋值就能复制索引数组
PHP 中的索引数组(即数字键数组)默认是值传递,$new = $old 就完成了浅拷贝。这不是“引用”,也不需要额外函数——只要没用 & 显式引用,变量赋值就是复制一份独立副本。
常见错误现象:$new[] = 'x' 后发现 $old 也变了?那说明你之前用了 $new = &$old 或在函数里传参时加了 &,不是赋值本身的问题。
- 适用场景:普通遍历、临时加工、避免修改原数组
- 性能影响:O(n) 时间 + 额外内存,但 PHP 7+ 的写时复制(Copy-on-Write)机制会让未修改时的内存开销几乎为零
- 注意:嵌套数组里的子数组仍为引用关系(浅拷贝),若需完全隔离,得用
array_map('unserialize', array_map('serialize', $old))或递归克隆
用 array_values() 强制重排键名再复制
如果原数组键名不连续(比如删过元素)、或混有字符串键但你想纯索引化,直接赋值会保留原有键。这时要先用 array_values() 归一化。
示例:$old = [1 => 'a', 3 => 'b']; $new = array_values($old); → [0 => 'a', 1 => 'b']
立即学习“PHP免费学习笔记(深入)”;
- 使用场景:后续要用
for循环、依赖0,1,2...下标、或传给只认纯索引的第三方函数 - 参数差异:
array_values()不改变原数组,只返回新数组;它会丢弃所有原始键,只留数值索引 - 兼容性:PHP 4.0.1+,无风险
避免 array_merge() 误用导致键名错乱
有人习惯用 array_merge($old) 来“复制”,这确实能生成新数组,但对索引数组会重排键名——看似没问题,可一旦原数组含字符串键(哪怕只有一个),array_merge() 会把数字键和字符串键分开处理,结果可能出人意料。
错误示范:$old = ['a', 'b', 'c']; $new = array_merge($old); → 正常;但若 $old = [0=>'a', 'x'=>'y', 1=>'b'],array_merge() 会把 'x'=>'y' 当作关联部分,数字键被重排成 [0=>'a', 1=>'b'],丢失键映射逻辑。
- 容易踩的坑:把
array_merge()当通用复制工具,忽略它对混合键的特殊行为 - 替代方案:纯索引数组就用
array_values($old);不确定键类型时,优先用直接赋值$new = $old - 性能提示:
array_merge()比直接赋值多一次键检查和重组,没必要时别绕弯
函数内返回数组副本要注意作用域
在函数中复制索引数组,最安全写法是直接 return $input;。PHP 函数返回值默认是副本,不会意外污染调用方数据。
但若函数参数用了引用(function foo(&$arr)),即使你在函数里做了 $copy = $arr,返回前没 unset 引用,外部变量仍可能被间接修改。
- 关键点:是否加
&决定行为,不是复制动作本身 - 调试技巧:用
var_dump(array_keys($arr))和===对比键名/值,确认是否真复制成功 - 容易被忽略的地方:foreach 循环里用
&$v修改值后,没及时unset($v),会导致后续赋值操作意外影响原数组



















