PHP写时复制在数组vs对象



我有一个关于PHP中copy one write优化的问题,我认为这个问题与这个问题不同,这个问题被标记为重复。我也不觉得这个问题在这里得到了解决。

根据我的观察,写时复制优化对数组和对象的工作方式似乎不同。对于数组,似乎只要有任何变化,无论数组有多深,都会发生复制。对于对象来说,写时复制似乎只在一个较浅的层次上。

考虑:

class B{
var $b;
function __construct($x) { $this->b = $x; }
}
$w = [new B(0)];
$x = $w; // $x references $w 
$x[0]->b = 1; // now $x does not reference $w 
$y = new B(0);
$z = $y; // $z references $y 
$z->b = 1; // $z still references $y 

我通过将$w, $x, $y和$z传入debug_zval_dump函数来确认这些引用。

谁能解释一下为什么会这样?我提供的第二个链接中的答案提到"只要不改变单个字节"。也许这就是我需要更好地理解的。我对PHP对象的心理模型一直是它们实际上是指针。$x[0]-> B = 1"没有改变,所以我认为这不是一个字节的改变。

我也不明白为什么对象在这方面的行为与数组不同。

这种行为是否正确地记录在某个地方,而不是必须阅读或发布堆栈溢出?PHP.net手册对该语言的更多理论细节没有帮助。例如,使用JavaScript,可以查看ECMAScript标准。这类事情在PHP中似乎不存在。

您可以简单地使用var_dump()来查看对象id,而不是尝试根据refcount来推断。

,

class B{
var $b;
function __construct($x) { $this->b = $x; }
}
$w = [new B(0)];
$x = $w;
$x[0]->b = 1;
var_dump($w, $x);
$y = new B(0);
$z = $y;
$z->b = 1;
var_dump($y, $z);

输出:

array(1) {
[0]=>
object(B)#1 (1) {
["b"]=>
int(1)
}
}
array(1) {
[0]=>
object(B)#1 (1) {
["b"]=>
int(1)
}
}
object(B)#2 (1) {
["b"]=>
int(1)
}
object(B)#2 (1) {
["b"]=>
int(1)
}

在这里,我们可以看到object(B)#1通过数组赋值被保留。

最新更新