PHP 底层视角:变量传递与 zval 的一次真实旅程
在 PHP 中,我们常说“函数参数是按值传递的”,但在 Zend 引擎底层,这句话并不完全准确。真正起作用的是 zval 结构体 + 引用计数 + 写时复制(Copy On Write)。
先看一段最常见的代码:
<?php
function change($a) {
$a[] = 4;
}
$arr = [1, 2, 3];
change($arr);
var_dump($arr);从语义上看,$arr 并没有被修改。但在底层,$arr 与 $a 起初指向同一个 zval,其 refcount 为 2。只有当 $a[] = 4 触发写操作时,Zend 引擎才发现该 zval 是“共享状态”,于是执行 COW:复制一份 zval 给 $a,再写入新值,而 $arr 仍指向原始内存。
也就是说,大部分“按值传递”在底层只是增加引用计数,并没有真实拷贝。这也是 PHP 在高频函数调用场景下仍能保持性能的重要原因。理解这一点,可以帮助我们避免在循环中无意义地修改变量,从而减少 COW 触发次数,降低内存和 CPU 压力。