1--TEST--
2Lazy objects: write to skipped property does not initialize object
3--FILE--
4<?php
5
6class C {
7    public $a;
8    public int $b = 1;
9    public int $c;
10
11    public function __construct() {
12        var_dump(__METHOD__);
13    }
14}
15
16function test(string $name, object $obj) {
17    printf("# %s:\n", $name);
18
19    $reflector = new ReflectionClass(C::class);
20    $reflector->getProperty('a')->skipLazyInitialization($obj);
21    $reflector->getProperty('b')->skipLazyInitialization($obj);
22    $reflector->getProperty('c')->skipLazyInitialization($obj);
23
24    var_dump($obj);
25    $obj->a = 2;
26    $obj->b = 2;
27    $obj->c = 2;
28    var_dump($obj);
29}
30
31$reflector = new ReflectionClass(C::class);
32
33$obj = $reflector->newLazyGhost(function ($obj) {
34    var_dump("initializer");
35    $obj->__construct();
36});
37
38test('Ghost', $obj);
39
40$obj = $reflector->newLazyProxy(function ($obj) {
41    var_dump("initializer");
42    return new C();
43});
44
45test('Proxy', $obj);
46
47--EXPECTF--
48# Ghost:
49object(C)#%d (2) {
50  ["a"]=>
51  NULL
52  ["b"]=>
53  int(1)
54  ["c"]=>
55  uninitialized(int)
56}
57object(C)#%d (3) {
58  ["a"]=>
59  int(2)
60  ["b"]=>
61  int(2)
62  ["c"]=>
63  int(2)
64}
65# Proxy:
66object(C)#%d (2) {
67  ["a"]=>
68  NULL
69  ["b"]=>
70  int(1)
71  ["c"]=>
72  uninitialized(int)
73}
74object(C)#%d (3) {
75  ["a"]=>
76  int(2)
77  ["b"]=>
78  int(2)
79  ["c"]=>
80  int(2)
81}
82