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

Steve Sheldon
  • 6,421
  • 3
  • 31
  • 35
ajx
  • 117
  • 1
  • 4

5 Answers5

29

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

Mark Tomlin
  • 8,593
  • 11
  • 57
  • 72
  • I've provided another example. – ajx Nov 19 '10 at 02:42
  • 6
    And this is fully explained in the manual. http://php.net/manual/en/function.debug-zval-dump.php – Mark Tomlin Nov 19 '10 at 02:45
  • @ajx, I've updated the answer. I hope you now understand. I would like to point out, your tripping over the understanding of how PHP handles variables internally. I understand this is hard to understand without knowledge of how the PHP parser and runtime handles variables within the scope of functions. I hope this makes more sense then the last update I had. – Mark Tomlin Nov 20 '10 at 02:49
  • @ajx, I really don't know what to tell you at this point. I've pretty much made the answer as readable as I could make it. – Mark Tomlin Nov 25 '10 at 04:57
  • @Mark: Why are you giving 500 bounty on this question? It seems already sufficiently answered in the manual (and here). – NikiC Apr 19 '11 at 08:19
  • @nikic, the OP did not like the answer, I wonder what the community thinks of my answer. I think I've done the best job I can, but I still was not awarded the answer, so I wonder if someone else will, and offering a 500 bounty will give this question attention. – Mark Tomlin Apr 20 '11 at 10:09
  • @Mark: If I'm not mistaken, you're going to lose the 500 points, since (a) you won't get the points back if you award the bounty to yourself, and (b) your answer was posted before you issued the bounty, so your answer is not eligible for auto-award. – phooji Apr 20 '11 at 14:23
  • 1
    @phooji, be that as it may, this question dose reserve a answer. – Mark Tomlin Apr 21 '11 at 01:22
7

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

debug_zval_dump

Steve Sheldon
  • 6,421
  • 3
  • 31
  • 35
2

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.

Mark Tomlin
  • 8,593
  • 11
  • 57
  • 72
1

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 :).

Mixxiphoid
  • 1,044
  • 6
  • 26
  • 46
1

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.