You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP访问嵌套数组时是否会进行数组复制?

关于PHP多维数组遍历访问时的副本/引用问题

嘿,这个问题问得相当有意思!正好可以聊聊PHP数组里非常关键的**写时复制(Copy-on-Write,COW)**机制——这就是决定你代码行为的核心。

先直接给结论:在你这段只读操作的代码里,完全不会生成数组副本,PHP会自动用内部的引用优化来避免不必要的内存开销。

具体细节拆解:

  • 默认情况下PHP数组是「值语义」,但它有个聪明的优化逻辑:只有当你尝试修改数组的时候,才会真正复制内存。
  • 当你执行$tmp = $arr时,PHP并没有把整个数组复制一份,只是让$tmp和$arr共享同一块内存,同时标记为「只读共享」状态。
  • 接下来的foreach循环里,$tmp = $tmp[$lvl]只是让$tmp指向原数组里的对应子数组节点,全程没有任何修改操作,所以PHP完全没必要复制数组——它只是调整了内部的指针指向,内存占用几乎没有变化。

验证小例子(用内存变化直观感受):

你可以用memory_get_usage()来测试这个过程:

$arr = ['lvl1' => ['lvl2' => ['lvl3' => 'test']]];
$path = ['lvl1', 'lvl2'];

echo '初始内存占用: ' . memory_get_usage() . PHP_EOL;

$tmp = $arr;
echo '赋值$tmp后内存: ' . memory_get_usage() . PHP_EOL; // 和初始值几乎一致,无复制

foreach($path as $lvl) {
    $tmp = $tmp[$lvl];
    echo "访问{$lvl}后内存: " . memory_get_usage() . PHP_EOL; // 内存变化极小,无数组复制
}

// 现在尝试修改$tmp,触发写时复制
$tmp['new_key'] = 'new_val';
echo '修改$tmp后内存: ' . memory_get_usage() . PHP_EOL; // 内存明显上涨,此时才生成了副本

补充说明:

只有当你对$tmp或者原数组$arr执行修改操作(比如赋值、unset、排序等)时,PHP才会立即复制一份独立的数组出来,确保修改不会影响到共享的原数组。而你的代码全程是只读/指针指向操作,所以完全不会触发副本生成。

内容的提问来源于stack exchange,提问作者Xriuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:49:43