reference/var/functions/debug-zval-dump.xml
d08d2e887fdc229f16748df96450c9b68c9a3076
...
...
@@ -3,17 +3,19 @@
3
3
<refentry xml:id="function.debug-zval-dump" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
4
4
<refnamediv>
5
5
<refname>debug_zval_dump</refname>
6
-
<refpurpose>Dumps a string representation of an internal zend value to output</refpurpose>
6
+
<refpurpose>Dumps a string representation of an internal zval structure to output</refpurpose>
7
7
</refnamediv>
8
8
<refsect1 role="description">
9
9
&reftitle.description;
10
10
<methodsynopsis>
11
11
<type>void</type><methodname>debug_zval_dump</methodname>
12
-
<methodparam><type>mixed</type><parameter>variable</parameter></methodparam>
13
-
<methodparam choice="opt"><type>mixed</type><parameter>...</parameter></methodparam>
12
+
<methodparam><type>mixed</type><parameter>value</parameter></methodparam>
13
+
<methodparam rep="repeat"><type>mixed</type><parameter>values</parameter></methodparam>
14
14
</methodsynopsis>
15
15
<para>
16
-
Dumps a string representation of an internal zend value to output.
16
+
Dumps a string representation of an internal zval (Zend value) structure to output.
17
+
This is mostly useful for understanding or debugging implementation details of the
18
+
Zend Engine or PHP extensions.
17
19
</para>
18
20
</refsect1>
19
21
<refsect1 role="parameters">
...
...
@@ -21,10 +23,18 @@
21
23
<para>
22
24
<variablelist>
23
25
<varlistentry>
24
-
<term><parameter>variable</parameter></term>
26
+
<term><parameter>value</parameter></term>
25
27
<listitem>
26
28
<para>
27
-
The variable being evaluated.
29
+
The variable or value to dump.
30
+
</para>
31
+
</listitem>
32
+
</varlistentry>
33
+
<varlistentry>
34
+
<term><parameter>values</parameter></term>
35
+
<listitem>
36
+
<para>
37
+
Further variables or values to dump.
28
38
</para>
29
39
</listitem>
30
40
</varlistentry>
...
...
@@ -45,68 +55,60 @@
45
55
<programlisting role="php">
46
56
<![CDATA[
47
57
<?php
48
-
$var1 = 'Hello World';
49
-
$var2 = '';
50
-

51
-
$var2 =& $var1;
58
+
$var1 = 'Hello';
59
+
$var1 .= ' World';
60
+
$var2 = $var1;
52
61

53
-
debug_zval_dump(&$var1);
62
+
debug_zval_dump($var1);
54
63
?>
55
64
]]>
56
65
</programlisting>
57
66
&example.outputs;
58
67
<screen>
59
68
<![CDATA[
60
-
&string(11) "Hello World" refcount(3)
69
+
string(11) "Hello World" refcount(3)
61
70
]]>
62
71
</screen>
63
72
</example>
64
73
</para>
65
74
<note>
66
-
<title>Beware the <literal>refcount</literal></title>
75
+
<title>Understanding the <literal>refcount</literal></title>
67
76
<para>
68
-
The <literal>refcount</literal> value returned by this function is
69
-
non-obvious in certain circumstances. For example, a developer might
70
-
expect the above example to indicate a <literal>refcount</literal> of
71
-
<literal>2</literal>. The third reference is created when actually
72
-
calling <function>debug_zval_dump</function>.
77
+
The <literal>refcount</literal> value shown by this function may be
78
+
surprising without a detailed understanding of the engine's implementation.
73
79
</para>
74
80
<para>
75
-
This behavior is further compounded when a variable is not passed to
76
-
<function>debug_zval_dump</function> by reference. To illustrate, consider
77
-
a slightly modified version of the above example:
81
+
The Zend Engine uses reference counting for two different purposes:
78
82
</para>
79
83
<para>
80
-
<example>
81
-
<title/>
82
-
<programlisting role="php">
83
-
<![CDATA[
84
-
<?php
85
-
$var1 = 'Hello World';
86
-
$var2 = '';
87
-

88
-
$var2 =& $var1;
89
-

90
-
debug_zval_dump($var1); // not passed by reference, this time
91
-
?>
92
-
]]>
93
-
</programlisting>
94
-
&example.outputs;
95
-
<screen>
96
-
<![CDATA[
97
-
string(11) "Hello World" refcount(1)
98
-
]]>
99
-
</screen>
100
-
</example>
84
+
<simplelist>
85
+
<member>
86
+
Optimizing memory usage using a technique called "copy on write",
87
+
where multiple variables holding the same value point to the same copy
88
+
in memory. When any of the variables is modified, it is pointed to a new
89
+
copy in memory, and the reference count on the original is decreased by 1.
90
+
</member>
91
+
<member>
92
+
Tracking variables which have been assigned or passed by reference (see
93
+
<link linkend="language.references">References Explained</link>). This
94
+
refcount is stored on a separate reference zval, pointing to the zval
95
+
for the current value. This additional zval is not currently shown by
96
+
<function>debug_zval_dump</function>.
97
+
</member>
98
+
</simplelist>
101
99
</para>
102
100
<para>
103
-
Why <literal>refcount(1)</literal>? Because a copy of <literal>$var1</literal> is
104
-
being made, when the function is called.
101
+
Because <function>debug_zval_dump</function> takes its input as normal
102
+
parameters, passed by value, the copy on write technique will be used
103
+
to pass them: rather than copying the data, the refcount will be increased
104
+
by one for the lifetime of the function call. If the function modified the
105
+
parameter after receiving it, then a copy would be made; since it does not,
106
+
it will show a refcount one higher than in the calling scope.
105
107
</para>
106
108
<para>
107
-
This function becomes even <emphasis>more</emphasis> confusing when a
108
-
variable with a <literal>refcount</literal> of <literal>1</literal> is
109
-
passed (by copy/value):
109
+
The parameter passing also prevents <function>debug_zval_dump</function>
110
+
showing variables which have been assigned by reference. To illustrate,
111
+
consider a slightly modified version of the above example:
110
112
</para>
111
113
<para>
112
114
<example>
...
...
@@ -114,7 +116,11 @@ string(11) "Hello World" refcount(1)
114
116
<programlisting role="php">
115
117
<![CDATA[
116
118
<?php
117
-
$var1 = 'Hello World';
119
+
$var1 = 'Hello';
120
+
$var1 .= ' World';
121
+
// Point three variables as references to the same value
122
+
$var2 =& $var1;
123
+
$var3 =& $var1;
118
124

119
125
debug_zval_dump($var1);
120
126
?>
...
...
@@ -129,25 +135,18 @@ string(11) "Hello World" refcount(2)
129
135
</example>
130
136
</para>
131
137
<para>
132
-
A <literal>refcount</literal> of <literal>2</literal>, here, is extremely
133
-
non-obvious. Especially considering the above examples. So what's
134
-
happening?
138
+
Although <varname>$var1</varname>, <varname>$var2</varname>, and
139
+
<varname>$var3</varname> are linked as references, only the
140
+
<emphasis>value</emphasis> is passed to <function>debug_zval_dump</function>.
141
+
That value is used once by the set of references, and once inside the
142
+
<function>debug_zval_dump</function>, so shows a refcount of 2.
135
143
</para>
136
144
<para>
137
-
When a variable has a single reference (as did <literal>$var1</literal>
138
-
before it was used as an argument to <function>debug_zval_dump</function>),
139
-
PHP's engine optimizes the manner in which it is passed to a function.
140
-
Internally, PHP treats <literal>$var1</literal> like a reference (in that
141
-
the <literal>refcount</literal> is increased for the scope of this
142
-
function), with the caveat that <emphasis>if</emphasis> the passed reference
143
-
happens to be written to, a copy is made, but only at the moment of
144
-
writing. This is known as "copy on write."
145
-
</para>
146
-
<para>
147
-
So, if <function>debug_zval_dump</function> happened to write to its sole
148
-
parameter (and it doesn't), then a copy would be made. Until then, the
149
-
parameter remains a reference, causing the <literal>refcount</literal> to
150
-
be incremented to <literal>2</literal> for the scope of the function call.
145
+
Further complications arise because of optimisations made in the engine for
146
+
different data types. Some types such as integers do not use "copy on write",
147
+
so do not show a refcount at all. In other cases, the refcount shows extra
148
+
copies used internally, such as when a literal string or array is stored as
149
+
part of a code instruction.
151
150
</para>
152
151
</note>
153
152
</refsect1>
...
...
@@ -163,7 +162,6 @@ string(11) "Hello World" refcount(2)
163
162
</para>
164
163
</refsect1>
165
164
</refentry>
166
-

167
165
<!-- Keep this comment at the end of the file
168
166
Local variables:
169
167
mode: sgml
170
168