对ZVals的澄清

Bea*_*use 4 php

我正在读这篇文章:http://www.dereleased.com/2011/04/27/the-importance-of-zvals-and-circular-references/

还有一个让我失望的例子.

$foo = &$bar;
$bar = &$foo;
$baz = 'baz';

$foo = &$baz;

var_dump($foo, $bar);
/*
string(3) "baz"
NULL
*/
Run Code Online (Sandbox Code Playgroud)

如果你一直在跟随,这应该是完美的意义.创建$ foo,并指向由$ bar标识的ZVal位置; 当$ bar创建时,它指向$ foo被指向的相同位置.当然,该位置为空.当$ foo被重新分配时,唯一改变的是ZVal $ foo指向的内容; 如果我们首先为$ foo分配了不同的值,那么$ bar仍将保留该值.

我学会了用C编程.我知道PHP是不同的,它使用ZVals而不是内存位置作为参考.但是当你运行这段代码时:

$foo = &$bar;
$bar = &$foo;
Run Code Online (Sandbox Code Playgroud)

在我看来,会有两个ZVals.在C中,将存在两个存储器位置(并且值将是相反的存储器位置).

谁能解释一下?

dec*_*eze 7

它主要归结为符号表的工作原理.这是一张有两面的桌子:

symbol name  |  value
-------------+-------
             |
Run Code Online (Sandbox Code Playgroud)

有趣的是,可以为一个值分配多个名称:

symbol name  |  value
-------------+-------
foo, bar     | 'baz'
Run Code Online (Sandbox Code Playgroud)

使用时分配符号时=,value表格的一侧会发生变化:

$baz = 42;

symbol name  |  value
-------------+-------
baz          | 42
Run Code Online (Sandbox Code Playgroud)

分配使用时=&,将symbol name边移动到值的任何位置:

$foo =& $baz;

symbol name  |  value
-------------+-------
baz, foo     | 42
Run Code Online (Sandbox Code Playgroud)

所以在你的例子中,从头开始:

$foo =& $bar;
($bar does not exist, is null, which is implicitly created,
 $foo is pointed to where the implicitly created $bar points)

symbol name  |  value
-------------+-------
foo, bar     | null


$bar = &$foo;
(no real change, $bar is pointed to where $foo is pointing)

symbol name  |  value
-------------+-------
foo, bar     | null


$baz = 'baz';

symbol name  |  value
-------------+-------
foo, bar     | null
baz          | 'baz'


$foo = &$baz;
($foo is pointed to where $baz is pointing)

symbol name  |  value
-------------+-------
bar          | null
baz, foo     | 'baz'
Run Code Online (Sandbox Code Playgroud)