$var = 1;
debug_zval_dump($var);
Run Code Online (Sandbox Code Playgroud)
输出:
long(1) refcount(2)
$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;
Run Code Online (Sandbox Code Playgroud)
输出:
long(1) refcount(1)
Run Code Online (Sandbox Code Playgroud)
UPDATE
对答案非常失望......
Mar*_*lin 28
void debug_zval_dump(mixed $ variable);
代码:
$var = 1; # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.
Run Code Online (Sandbox Code Playgroud)
输出:
long(1) refcount(2)
Run Code Online (Sandbox Code Playgroud)
说明:当$ var的refcount为1时,PHP会对此进行优化并直接处理内存而不是复制,因为不会有任何污染任何其他引用的可能性.PHP通过引用在内部传递$ var,以便它可以在需要时直接编辑内存.实际调用debug_zval_dump()时会创建第二个引用.
这里的refcount 2非常不明显.那么发生了什么?
当一个变量有一个引用时(就像它被用作debug_zval_dump()的参数之前的$ var),PHP的引擎优化了它传递给函数的方式.在内部,PHP将$ var视为一个引用(因为该函数的范围增加了引用计数),但需要注意的是,如果传递的引用恰好被写入,则复制,但仅在写入时.这被称为"写入时复制".
因此,如果debug_zval_dump()碰巧写入其唯一参数(并且没有),那么将进行复制.在此之前,该参数仍然是一个引用,导致refcount在函数调用的范围内递增到2.
代码:
$var = 1; # $var's Refcount = 1
$var_dup = &$var; # $var's Refcount = 2
debug_zval_dump($var); # A copy is passed as $var's refcount is 2.
Run Code Online (Sandbox Code Playgroud)
输出:
long(1) refcount(1)
Run Code Online (Sandbox Code Playgroud)
说明:这次调用函数时会生成$ var的副本.这是因为$ var被引用两次而且PHP不想污染任何其他引用,因此它为$ self创建了一个副本.因为现在有一个单独的内存只用于函数调用的范围,它只有一个引用,它是自己的.因此,对于函数的范围,副本的引用计数为1(它是自己的).