1--TEST--
2Lazy objects: Foreach initializes object
3--FILE--
4<?php
5
6#[AllowDynamicProperties]
7class C {
8    public int $a;
9    public int $b {
10        get { return $this->b; }
11        set(int $value) { $this->b = $value; }
12    }
13    public int $c {
14        get { return $this->a + 2; }
15    }
16    public function __construct() {
17        var_dump(__METHOD__);
18        $this->a = 1;
19        $this->b = 2;
20        $this->d = 4;
21    }
22}
23
24$reflector = new ReflectionClass(C::class);
25
26print "# Ghost:\n";
27
28$obj = $reflector->newLazyGhost(function ($obj) {
29    var_dump("initializer");
30    $obj->__construct();
31});
32
33foreach ($obj as $prop => $value) {
34    var_dump($prop, $value);
35}
36
37print "# Proxy:\n";
38
39$obj = $reflector->newLazyProxy(function ($obj) {
40    var_dump("initializer");
41    return new C();
42});
43
44foreach ($obj as $prop => $value) {
45    var_dump($prop, $value);
46}
47
48print "# Ghost (init exception):\n";
49
50$obj = $reflector->newLazyGhost(function ($obj) {
51    throw new \Exception();
52});
53
54try {
55    var_dump(json_encode($obj));
56} catch (\Exception $e) {
57    printf("%s: %s\n", $e::class, $e->getMessage());
58}
59
60print "# Proxy (init exception):\n";
61
62$obj = $reflector->newLazyProxy(function ($obj) {
63    throw new \Exception();
64});
65
66try {
67    var_dump(json_encode($obj));
68} catch (\Exception $e) {
69    printf("%s: %s\n", $e::class, $e->getMessage());
70}
71
72--EXPECT--
73# Ghost:
74string(11) "initializer"
75string(14) "C::__construct"
76string(1) "a"
77int(1)
78string(1) "b"
79int(2)
80string(1) "c"
81int(3)
82string(1) "d"
83int(4)
84# Proxy:
85string(11) "initializer"
86string(14) "C::__construct"
87string(1) "a"
88int(1)
89string(1) "b"
90int(2)
91string(1) "c"
92int(3)
93# Ghost (init exception):
94Exception:
95# Proxy (init exception):
96Exception:
97