8
  $var = 1;
  debug_zval_dump($var);

输出:

long(1) refcount(2)


  $var = 1;
  $var_dup = &$var;
  debug_zval_dump($var);exit;

输出 :

long(1) refcount(1)

更新

对答案很失望...

4

5 回答 5

29

无效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 的 refcount 为 1,PHP 对其进行优化并直接处理内存而不是复制,因为没有机会污染任何其他引用。PHP 在内部通过引用传递 $var,因此它也可以在需要时直接编辑内存。第二个引用是在实际调用 debug_zval_dump() 时创建的。

此处的 refcount 为 2 非常不明显。那么发生了什么?

当一个变量只有一个引用时(就像 $var 在用作 debug_zval_dump() 的参数之前所做的那样),PHP 的引擎会优化将它传递给函数的方式。在内部,PHP 将 $var 视为一个引用(因为该函数的范围内 refcount 增加了),但需要注意的是,如果传递的引用恰好被写入,则会制作一个副本,但仅在写入时. 这称为“写时复制”。

因此,如果 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 不想污染任何其他引用,所以它制作了 $var 的副本以供自己处理。由于现在有一块单独的内存仅用于函数调用的范围,因此它只有一个引用,它是 self。因此,对于函数的范围,副本的引用计数为 1(它是自身)。

于 2010-11-19T02:41:26.273 回答
7

我认为此方法的文档在“注意参考计数”部分对此进行了解释:

debug_zval_dump

于 2011-04-22T13:55:16.390 回答
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 变量在 write时被复制,创建了该变量的全新单独实例,并且因为 debug_zval_dump 正在处理 $var 的全新副本,而不是引用,所以它的 refcount 为 1。一旦功能完成。

希望清除它。

于 2011-04-25T08:41:57.360 回答
1

我将尝试对debug_zval_dump()函数和处理变量的方式进行更多说明。如果我错了,不要杀我:)...

  $var = 1;
  debug_zval_dump($var);

我认为调试函数会计算$varrefcount(1) 和 1 refcount(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)......为什么它是 refcount 1?如您所见,$var_dup 的值从未分配给 3,它应该是 2 对吧?不,不应该,因为您使用 &$var 使其保持最新状态。这意味着当您过去时$var = 4$var = 3$ debug_zval_dump($var_dup);exit;var_dup 的值将自动更新,因为您已链接它们,使其成为 1 refcount。

然后还有另外一种情况:

$var = 2;
$var_dup = $var;
$var = 4;
debug_zval_dump($var_dup);exit;

这个的输出是:long(2) refcount(2). 如您所见, $var_dup 的值是正确的。$var 是 2,该值是通过 $var_dup 传递的,他坚持使用它。refcount 是 2 因为是 counts$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

免责声明
我不知道这个功能的目的是什么。直到今天我才真正听说过。所以我不对不当使用负责:)。

于 2011-04-19T17:22:20.270 回答
1

此处的 refcount 为 2 非常不明显。特别是考虑到上面的例子。那么发生了什么?

当一个变量只有一个引用时(就像 $var1 在它被用作 debug_zval_dump() 的参数之前所做的那样),PHP 的引擎会优化它传递给函数的方式。在内部,PHP 将 $var1 视为一个引用(因为该函数的范围内 refcount 增加了),但需要注意的是,如果传递的引用恰好被写入,则会制作一个副本,但仅在写入时. 这称为“写时复制”。

因此,如果 debug_zval_dump() 碰巧写入了它的唯一参数(但它没有),那么就会制作一个副本。在那之前,参数仍然是一个引用,导致函数调用范围内的 refcount 增加到 2。

-- 学分转到 php 手册。阅读该功能附带的完整说明,您甚至应该问过它。

--- 编辑:糟糕,我应该在回答之前阅读更多评论:D 无论如何,这就是前面提到的问题的答案。

于 2011-04-19T18:02:52.033 回答