Why the refcount is 2 not 1?

2019-02-09 16:09发布

  $var = 1;
  debug_zval_dump($var);

Output:

long(1) refcount(2)


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

Output :

long(1) refcount(1)

UPDATE

Very disapointed at the answer...

5条回答
女痞
2楼-- · 2019-02-09 16:28

Code:

$var = 1;
debug_zval_dump($var);

Output: long(1) refcount(2)

Explanation: When a variable has a single reference, as did $var before it was used as an argument to debug_zval_dump(), PHP's engine optimizes the manner in which it is passed to a function. PHP, basically makes a pointer to the variable and internally, PHP treats $var like a reference and so it's refcount is increased for the scope of this function.

Code:

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

Output: long(1) refcount(1)

Explanation: Here the $var variable is copyied on write, making whole new seprate instance of that varable and because debug_zval_dump is dealing with a whole new copy of $var, not a reference, it's refcount is 1. The copy is then destroyed once the function is done.

Hope that clears it up.

查看更多
霸刀☆藐视天下
3楼-- · 2019-02-09 16:31

I think the documentation for this method explains this under the section "Beware the Ref Count":

debug_zval_dump

查看更多
闹够了就滚
4楼-- · 2019-02-09 16:36

I'll try to give some more light to the debug_zval_dump() function and the way you process your variables. Don't kill me if I'm wrong :)...

  $var = 1;
  debug_zval_dump($var);

I think the debug function counts the $var refcount(1) and the 1 refcount(2) since 1 is the value of $var.
If you look at it logically you are actually saying this.

  1 = 1;
  debug_zval_dump(1);

Second part:

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

What you see here is that you set $var to $var_dup but is keeping its value. The refcount of $var is 1 because you 'linked' it to $var_dup.

$var = 2;
$var_dup = &$var; //or $var = &$var_dup; (doesn't matter which one)
$var = 3;
debug_zval_dump($var_dup);exit;

This gives long(3) refcount(1)... Why is it refcount 1? As you can see the value of $var_dup was never assigned to 3, it should be 2 right? No it shouldn't because you keep it up to date with &$var. This means that when you past $var = 4 between $var = 3 and debug_zval_dump($var_dup);exit; the value of $var_dup will be updated automatically because you have linked them, making it 1 refcount.

Then there is this other occurrence:

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

The output of this is: long(2) refcount(2). As you can see the value of $var_dup is correct. $var was 2, the value was passed through $var_dup an he sticked with it. The refcount is 2 because is counts $var = 4; and $var_dup = $var;. When we remove the $var = 4; we get this:

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

The output of this is: long(2) refcount(3). Now the debug function count the following: $var_dup(1), =$var(2) (since $var_dup was originated from $var) and $var(= 2;)(3).

I'll hope you understand what I mean. In my opinion this is more math then programming, so that may be the reason why it is a difficult function to understand.

And again, if I'm wrong, don't kill me :)...
Greetings,
Mixxiphoid

Disclaimer
I do not know what the purpose is of this function. I actually never heard of it until today. So I'm not responsible for inappropriate use :).

查看更多
姐就是有狂的资本
5楼-- · 2019-02-09 16:42

A refcount of 2, here, is extremely non-obvious. Especially considering the above examples. So what's happening?

When a variable has a single reference (as did $var1 before it was used as an argument to debug_zval_dump()), PHP's engine optimizes the manner in which it is passed to a function. Internally, PHP treats $var1 like a reference (in that the refcount is increased for the scope of this function), with the caveat that if the passed reference happens to be written to, a copy is made, but only at the moment of writing. This is known as "copy on write."

So, if debug_zval_dump() happened to write to its sole parameter (and it doesn't), then a copy would be made. Until then, the parameter remains a reference, causing the refcount to be incremented to 2 for the scope of the function call.

-- Credits go to the php manual. Read the whole description that comes with the function and you should've even has asked it.

--- Edit: Woops, I should read more comments before answering :D Anyways, this is the answer to the question as mentioned before.

查看更多
甜甜的少女心
6楼-- · 2019-02-09 16:52

void debug_zval_dump ( mixed $variable );


Code:

$var = 1;              # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.

Output:

long(1) refcount(2)

Explanation: As $var's refcount is 1, PHP optimizes this and handles the memory directly instead of making a copy because there is no chance of contaminating any other references. PHP internally passing $var by reference, so that it can edit the memory directly if it needs too. The second reference is created when actually calling debug_zval_dump().

A refcount of 2, here, is extremely non-obvious. So what's happening?

When a variable has a single reference (as did $var before it was used as an argument to debug_zval_dump()), PHP's engine optimizes the manner in which it is passed to a function. Internally, PHP treats $var like a reference (in that the refcount is increased for the scope of this function), with the caveat that if the passed reference happens to be written to, a copy is made, but only at the moment of writing. This is known as "copy on write."

So, if debug_zval_dump() happened to write to its sole parameter (and it doesn't), then a copy would be made. Until then, the parameter remains a reference, causing the refcount to be incremented to 2 for the scope of the function call.


Code:

$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.

Output:

long(1) refcount(1)

Explanation: This time a copy of $var is being made when the function is called. This is because $var is referenced twice and PHP does not want to contaminate any other references so it makes a copy of $var for it's self to work on. As there is now a separate piece of memory that is only used for the scope of the function call it only has one refrence, it's self. So for the scope of the function the copy's refcount is 1 (it's self).

查看更多
登录 后发表回答