diff --git a/reference/var/functions/debug-zval-dump.xml b/reference/var/functions/debug-zval-dump.xml index 25002e4177..69137282c0 100644 --- a/reference/var/functions/debug-zval-dump.xml +++ b/reference/var/functions/debug-zval-dump.xml @@ -3,7 +3,7 @@ debug_zval_dump - Dumps a string representation of an internal zend value to output + Dumps a string representation of an internal zval structure to output &reftitle.description; @@ -13,7 +13,9 @@ mixedvalues - Dumps a string representation of an internal zend value to output. + Dumps a string representation of an internal zval (Zend value) structure to output. + This is mostly useful for understanding or debugging implementation details of the + Zend Engine or PHP extensions. @@ -24,7 +26,7 @@ value - The variable to dump. + The variable or value to dump. @@ -32,7 +34,7 @@ values - Further variables to dump. + Further variables or values to dump. @@ -53,36 +55,60 @@ ]]> &example.outputs; - Beware the <literal>refcount</literal> + Understanding the <literal>refcount</literal> - The refcount value returned by this function is - non-obvious in certain circumstances. For example, a developer might - expect the above example to indicate a refcount of - 2. The third reference is created when actually - calling debug_zval_dump. + The refcount value shown by this function may be + surprising without a detailed understanding of the engine's implementation. - This behavior is further compounded when a variable is not passed to - debug_zval_dump by reference. To illustrate, consider - a slightly modified version of the above example: + The Zend Engine uses reference counting for two different purposes: + + + + + Optimizing memory usage using a technique called "copy on write", + where multiple variables holding the same value point to the same copy + in memory. When any of the variables is modified, it is pointed to a new + copy in memory, and the reference count on the original is decreased by 1. + + + Tracking variables which have been assigned or passed by reference (see + References Explained). This + refcount is stored on a separate reference zval, pointing to the zval + for the current value. This additional zval is not currently shown by + debug_zval_dump. + + + + + Because debug_zval_dump takes its input as normal + parameters, passed by value, the copy on write technique will be used + to pass them: rather than copying the data, the refcount will be increased + by one for the lifetime of the function call. If the function modified the + parameter after receiving it, then a copy would be made; since it does not, + it will show a refcount one higher than in the calling scope. + + + The parameter passing also prevents debug_zval_dump + showing variables which have been assigned by reference. To illustrate, + consider a slightly modified version of the above example: @@ -90,39 +116,11 @@ debug_zval_dump(&$var1); -]]> - - &example.outputs; - - - - - - - Why refcount(1)? Because a copy of $var1 is - being made, when the function is called. - - - This function becomes even more confusing when a - variable with a refcount of 1 is - passed (by copy/value): - - - - - <programlisting role="php"> -<![CDATA[ -<?php -$var1 = 'Hello World'; +$var3 =& $var1; debug_zval_dump($var1); ?> @@ -137,25 +135,18 @@ string(11) "Hello World" refcount(2) </example> </para> <para> - A <literal>refcount</literal> of <literal>2</literal>, here, is extremely - non-obvious. Especially considering the above examples. So what's - happening? + Although <varname>$var1</varname>, <varname>$var2</varname>, and + <varname>$var3</varname> are linked as references, only the + <emphasis>value</emphasis> is passed to <function>debug_zval_dump</function>. + That value is used once by the set of references, and once inside the + <function>debug_zval_dump</function>, so shows a refcount of 2. </para> <para> - When a variable has a single reference (as did <literal>$var1</literal> - before it was used as an argument to <function>debug_zval_dump</function>), - PHP's engine optimizes the manner in which it is passed to a function. - Internally, PHP treats <literal>$var1</literal> like a reference (in that - the <literal>refcount</literal> is increased for the scope of this - function), with the caveat that <emphasis>if</emphasis> 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." - </para> - <para> - So, if <function>debug_zval_dump</function> 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 <literal>refcount</literal> to - be incremented to <literal>2</literal> for the scope of the function call. + Further complications arise because of optimisations made in the engine for + different data types. Some types such as integers do not use "copy on write", + so do not show a refcount at all. In other cases, the refcount shows extra + copies used internally, such as when a literal string or array is stored as + part of a code instruction. </para> </note> </refsect1>