为什么refcount是2而不是1?

ajx*_*ajx 8 php refcounting

  $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(它是自己的).

  • 这在手册中有详细说明.http://php.net/manual/en/function.debug-zval-dump.php (6认同)

Ste*_*don 7

我认为这种方法的文档在"注意参考计数"部分解释了这一点:

debug_zval_dump