1--TEST--
2Lazy objects: skipLazyInitialization() preserves readonly semantics
3--FILE--
4<?php
5
6class C {
7    public function __construct() {
8        $this->a = 1;
9    }
10    public readonly int $a;
11    public $b;
12}
13
14function test(string $name, object $obj) {
15    printf("# %s\n", $name);
16
17    $reflector = new ReflectionClass(C::class);
18    $reflector->getProperty('a')->skipLazyInitialization($obj);
19
20    try {
21        var_dump($obj->a);
22    } catch (Error $e) {
23        printf("%s: %s\n", $e::class, $e->getMessage());
24    }
25    var_dump(!$reflector->isUninitializedLazyObject($obj));
26    var_dump($obj);
27
28    $reflector->initializeLazyObject($obj);
29    var_dump($obj);
30}
31
32$reflector = new ReflectionClass(C::class);
33$obj = $reflector->newLazyGhost(function ($obj) {
34    $obj->__construct();
35});
36
37test('Ghost', $obj);
38
39$obj = $reflector->newLazyProxy(function () {
40    return new C();
41});
42
43test('Proxy', $obj);
44
45?>
46--EXPECTF--
47# Ghost
48Error: Typed property C::$a must not be accessed before initialization
49bool(false)
50lazy ghost object(C)#%d (0) {
51  ["a"]=>
52  uninitialized(int)
53}
54object(C)#%d (2) {
55  ["a"]=>
56  int(1)
57  ["b"]=>
58  NULL
59}
60# Proxy
61Error: Typed property C::$a must not be accessed before initialization
62bool(false)
63lazy proxy object(C)#%d (0) {
64  ["a"]=>
65  uninitialized(int)
66}
67lazy proxy object(C)#%d (1) {
68  ["instance"]=>
69  object(C)#%d (2) {
70    ["a"]=>
71    int(1)
72    ["b"]=>
73    NULL
74  }
75}
76