$var = 1;
debug_zval_dump($var);
输出:
long(1) refcount(2)
$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;
输出:
long(1) refcount(1)
更新
对答案非常不满......
答案 0 :(得分:28)
void debug_zval_dump(混合 $ variable );
<强>代码强>:
$var = 1; # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.
<强>输出强>:
long(1) refcount(2)
<强>解释强>: 由于$ var的引用计数为1,PHP会对此进行优化并直接处理内存而不是复制,因为没有机会污染任何其他引用。 PHP通过引用在内部传递$ var,以便它可以在需要时直接编辑内存。实际调用debug_zval_dump()时会创建第二个引用。
这里的引用数量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.
<强>输出强>:
long(1) refcount(1)
<强>解释强>: 这次调用函数时会生成$ var的副本。这是因为$ var被引用两次而且PHP不想污染任何其他引用,因此它为$ self创建了一个副本。因为现在有一个单独的内存只用于函数调用的范围,它只有一个引用,它是自己的。因此,对于函数的范围,副本的引用计数为1(它是自己的)。
答案 1 :(得分:7)
我认为此方法的文档在“注意参考计数”部分解释了这一点:
答案 2 :(得分:2)
<强>代码强>:
$var = 1;
debug_zval_dump($var);
输出:long(1) refcount(2)
解释:当一个变量有一个引用时,就像$ var被用作debug_zval_dump()的参数一样,PHP的引擎优化了它传递给函数的方式。 PHP,基本上是一个指向变量的指针,内部,PHP将$ var视为一个引用,所以它的refcount会增加这个函数的范围。
<强>代码强>:
$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;
输出:long(1) refcount(1)
解释:这里$ var变量是copyied on write,构成了该变量的全新seprate实例,因为debug_zval_dump正在处理$ var的全新副本,而不是引用,它的引用计数是1.一旦功能完成,副本就会被销毁。
希望能够解决它。
答案 3 :(得分:1)
我将尝试更多地了解debug_zval_dump()
函数以及处理变量的方式。如果我错了,不要杀我:)......
$var = 1;
debug_zval_dump($var);
我认为调试函数会计算$var
引用计数(1)和1引用计数(2),因为1是$var
的值。
如果你从逻辑上看它,你实际上是在说这个。
1 = 1;
debug_zval_dump(1);
第二部分:
$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;
您在此处看到的是,您将$var
设置为$var_dup
,但保留其值。 $var
的引用计数为1,因为您已将其“链接”到$var_dup
。
$var = 2;
$var_dup = &$var; //or $var = &$var_dup; (doesn't matter which one)
$var = 3;
debug_zval_dump($var_dup);exit;
这会给long(3) refcount(1)
...为什么它会引用1?正如您所看到的,$ var_dup的值从未分配给3,它应该是2对吗?不,不应该因为你用&amp; $ var保持最新。这意味着,当您在$var = 4
和$var = 3
之间经过debug_zval_dump($var_dup);exit;
后,$ var_dup的值将自动更新,因为您已将其链接,并将其设为1引用。
然后还有另一种情况:
$var = 2;
$var_dup = $var;
$var = 4;
debug_zval_dump($var_dup);exit;
这个输出是:long(2) refcount(2)
。
正如您所看到的,$ var_dup的值是正确的。 $ var是2,该值是通过$ var_dup传递的,他坚持使用它。引用计数为2,因为它是$var = 4;
和$var_dup = $var;
。
当我们移除$var = 4;
时,我们得到了这个:
$var = 2;
$var_dup = $var;
debug_zval_dump($var_dup);exit;
这个输出是:long(2) refcount(3)
。
现在调试函数计算如下:$var_dup
(1),=$var
(2)(因为$ var_dup源自$ var)和$var
(= 2;
)(3) )。
我希望你明白我的意思。在我看来,这是更多的数学然后编程,所以这可能是它难以理解的原因。
而且,如果我错了,不要杀了我:)
问候,
Mixxiphoid
<强>声明强>
我不知道这个功能的目的是什么。直到今天我才真正听说过它。因此,我不负责使用不当:)。
答案 4 :(得分:1)
这里的引用数量2非常不明显。特别是考虑到上面的例子。那么发生了什么?
当一个变量有一个引用时(在将它作为debug_zval_dump()的参数之前使用$ var1),PHP的引擎会优化它传递给函数的方式。在内部,PHP将$ var1视为一个引用(因为该函数的范围增加了引用计数),但需要注意的是,如果传递的引用恰好被写入,则复制,但仅在写入时。这被称为“写作时复制”。
因此,如果debug_zval_dump()碰巧写入其唯一参数(并且没有),那么将进行复制。在此之前,该参数仍然是一个引用,导致refcount在函数调用的范围内递增到2。
- 积分转到php手册。阅读该功能附带的整个说明,你甚至应该问过它。
---编辑: Woops,我应该在回答之前阅读更多评论:D无论如何,这是前面提到的问题的答案。