1--TEST--
2Test debug_zval_dump() function : working on objects
3--SKIPIF--
4<?php if (PHP_ZTS) { print "skip only for no-zts build"; }
5--INI--
6opcache.enable=0
7--FILE--
8<?php
9function zval_dump( $values ) {
10  $counter = 1;
11  foreach( $values as $value ) {
12    echo "-- Iteration $counter --\n";
13    debug_zval_dump( $value );
14    $counter++;
15  }
16}
17
18/* checking on objects type */
19echo "*** Testing debug_zval_dump() on objects ***\n";
20#[AllowDynamicProperties]
21class object_class {
22  var $value1 = 1;
23  private $value2 = 10;
24  protected $value3 = 20;
25  public $value4 = 30;
26
27  private function foo1() {
28    echo "function foo1\n";
29  }
30  protected function foo2() {
31    echo "function foo2\n";
32  }
33  public function foo3() {
34    echo "function foo3\n";
35  }
36  public $array_var  = array( "key1" => 1, "key2 " => 3);
37
38  function __construct () {
39      $this->value1 = 5;
40      $this->object_class1 = $this;
41  }
42}
43
44class no_member_class{
45//no members
46}
47
48/* class with member as object of other class */
49#[AllowDynamicProperties]
50class contains_object_class
51{
52   var       $p = 30;
53   protected $p1 = 40;
54   private   $p2 = 50;
55   var       $class_object1;
56   public    $class_object2;
57   private   $class_object3;
58   protected $class_object4;
59   var       $no_member_class_object;
60
61   public function func() {
62     echo "func() is called \n";
63   }
64
65   function __construct () {
66     $this->class_object1 = new object_class();
67     $this->class_object2 = new object_class();
68     $this->class_object3 = $this->class_object1;
69     $this->class_object4 = $this->class_object2;
70     $this->no_member_class_object = new no_member_class();
71     $this->class_object5 = $this;   //recursive reference
72   }
73}
74
75/* creating new object $obj */
76$obj = new contains_object_class();
77$obj1 = & $obj;  //object $obj1 references object $obj
78$obj2 = & $obj;
79$obj3 = & $obj2;
80
81/* object which is unset */
82$unset_obj = new object_class();
83unset($unset_obj);
84
85$objects = array (
86  new object_class,
87  new no_member_class,
88  $obj,
89  $obj->class_object1,
90  $obj->class_object2,
91  $obj->no_member_class_object,
92  @$temp_class_obj,  //undefined object
93  $obj2->class_object1,
94  $obj3->class_object2,
95  $obj2->class_object1->value4,
96  @$unset_obj
97);
98/* using zval_dump() to dump out the objects and its reference count */
99zval_dump($objects);
100
101$int_var = 500;
102$obj = $int_var;  //$obj is lost, $obj1,$obj2,$obj3,$obj4 = 500
103echo "\n-- Testing debug_zval_dump() on overwritten object variables --\n";
104debug_zval_dump($obj, $obj1, $obj2, $obj3);
105
106echo "\n-- Testing debug_zval_dump() on objects having circular reference --\n";
107$recursion_obj1 = new object_class();
108$recursion_obj2 = new object_class();
109$recursion_obj1->obj = &$recursion_obj2;  //circular reference
110$recursion_obj2->obj = &$recursion_obj1;  //circular reference
111debug_zval_dump($recursion_obj2);
112
113echo "Done\n";
114?>
115--EXPECTF--
116*** Testing debug_zval_dump() on objects ***
117-- Iteration 1 --
118object(object_class)#%d (6) refcount(%d){
119  ["value1"]=>
120  int(5)
121  ["value2":"object_class":private]=>
122  int(10)
123  ["value3":protected]=>
124  int(20)
125  ["value4"]=>
126  int(30)
127  ["array_var"]=>
128  array(2) refcount(%d){
129    ["key1"]=>
130    int(1)
131    ["key2 "]=>
132    int(3)
133  }
134  ["object_class1"]=>
135  *RECURSION*
136}
137-- Iteration 2 --
138object(no_member_class)#%d (0) refcount(%d){
139}
140-- Iteration 3 --
141object(contains_object_class)#%d (9) refcount(%d){
142  ["p"]=>
143  int(30)
144  ["p1":protected]=>
145  int(40)
146  ["p2":"contains_object_class":private]=>
147  int(50)
148  ["class_object1"]=>
149  object(object_class)#%d (6) refcount(%d){
150    ["value1"]=>
151    int(5)
152    ["value2":"object_class":private]=>
153    int(10)
154    ["value3":protected]=>
155    int(20)
156    ["value4"]=>
157    int(30)
158    ["array_var"]=>
159    array(2) refcount(%d){
160      ["key1"]=>
161      int(1)
162      ["key2 "]=>
163      int(3)
164    }
165    ["object_class1"]=>
166    *RECURSION*
167  }
168  ["class_object2"]=>
169  object(object_class)#%d (6) refcount(%d){
170    ["value1"]=>
171    int(5)
172    ["value2":"object_class":private]=>
173    int(10)
174    ["value3":protected]=>
175    int(20)
176    ["value4"]=>
177    int(30)
178    ["array_var"]=>
179    array(2) refcount(%d){
180      ["key1"]=>
181      int(1)
182      ["key2 "]=>
183      int(3)
184    }
185    ["object_class1"]=>
186    *RECURSION*
187  }
188  ["class_object3":"contains_object_class":private]=>
189  object(object_class)#%d (6) refcount(%d){
190    ["value1"]=>
191    int(5)
192    ["value2":"object_class":private]=>
193    int(10)
194    ["value3":protected]=>
195    int(20)
196    ["value4"]=>
197    int(30)
198    ["array_var"]=>
199    array(2) refcount(%d){
200      ["key1"]=>
201      int(1)
202      ["key2 "]=>
203      int(3)
204    }
205    ["object_class1"]=>
206    *RECURSION*
207  }
208  ["class_object4":protected]=>
209  object(object_class)#%d (6) refcount(%d){
210    ["value1"]=>
211    int(5)
212    ["value2":"object_class":private]=>
213    int(10)
214    ["value3":protected]=>
215    int(20)
216    ["value4"]=>
217    int(30)
218    ["array_var"]=>
219    array(2) refcount(%d){
220      ["key1"]=>
221      int(1)
222      ["key2 "]=>
223      int(3)
224    }
225    ["object_class1"]=>
226    *RECURSION*
227  }
228  ["no_member_class_object"]=>
229  object(no_member_class)#%d (0) refcount(%d){
230  }
231  ["class_object5"]=>
232  *RECURSION*
233}
234-- Iteration 4 --
235object(object_class)#%d (6) refcount(%d){
236  ["value1"]=>
237  int(5)
238  ["value2":"object_class":private]=>
239  int(10)
240  ["value3":protected]=>
241  int(20)
242  ["value4"]=>
243  int(30)
244  ["array_var"]=>
245  array(2) refcount(%d){
246    ["key1"]=>
247    int(1)
248    ["key2 "]=>
249    int(3)
250  }
251  ["object_class1"]=>
252  *RECURSION*
253}
254-- Iteration 5 --
255object(object_class)#%d (6) refcount(%d){
256  ["value1"]=>
257  int(5)
258  ["value2":"object_class":private]=>
259  int(10)
260  ["value3":protected]=>
261  int(20)
262  ["value4"]=>
263  int(30)
264  ["array_var"]=>
265  array(2) refcount(%d){
266    ["key1"]=>
267    int(1)
268    ["key2 "]=>
269    int(3)
270  }
271  ["object_class1"]=>
272  *RECURSION*
273}
274-- Iteration 6 --
275object(no_member_class)#%d (0) refcount(%d){
276}
277-- Iteration 7 --
278NULL
279-- Iteration 8 --
280object(object_class)#%d (6) refcount(%d){
281  ["value1"]=>
282  int(5)
283  ["value2":"object_class":private]=>
284  int(10)
285  ["value3":protected]=>
286  int(20)
287  ["value4"]=>
288  int(30)
289  ["array_var"]=>
290  array(2) refcount(%d){
291    ["key1"]=>
292    int(1)
293    ["key2 "]=>
294    int(3)
295  }
296  ["object_class1"]=>
297  *RECURSION*
298}
299-- Iteration 9 --
300object(object_class)#%d (6) refcount(%d){
301  ["value1"]=>
302  int(5)
303  ["value2":"object_class":private]=>
304  int(10)
305  ["value3":protected]=>
306  int(20)
307  ["value4"]=>
308  int(30)
309  ["array_var"]=>
310  array(2) refcount(%d){
311    ["key1"]=>
312    int(1)
313    ["key2 "]=>
314    int(3)
315  }
316  ["object_class1"]=>
317  *RECURSION*
318}
319-- Iteration 10 --
320int(30)
321-- Iteration 11 --
322NULL
323
324-- Testing debug_zval_dump() on overwritten object variables --
325int(500)
326int(500)
327int(500)
328int(500)
329
330-- Testing debug_zval_dump() on objects having circular reference --
331object(object_class)#%d (7) refcount(%d){
332  ["value1"]=>
333  int(5)
334  ["value2":"object_class":private]=>
335  int(10)
336  ["value3":protected]=>
337  int(20)
338  ["value4"]=>
339  int(30)
340  ["array_var"]=>
341  array(2) refcount(%d){
342    ["key1"]=>
343    int(1)
344    ["key2 "]=>
345    int(3)
346  }
347  ["object_class1"]=>
348  *RECURSION*
349  ["obj"]=>
350  reference refcount(2) {
351    object(object_class)#8 (7) refcount(2){
352      ["value1"]=>
353      int(5)
354      ["value2":"object_class":private]=>
355      int(10)
356      ["value3":protected]=>
357      int(20)
358      ["value4"]=>
359      int(30)
360      ["array_var"]=>
361      array(2) refcount(7){
362        ["key1"]=>
363        int(1)
364        ["key2 "]=>
365        int(3)
366      }
367      ["object_class1"]=>
368      *RECURSION*
369      ["obj"]=>
370      reference refcount(2) {
371        *RECURSION*
372      }
373    }
374  }
375}
376Done
377