1--TEST--
2Lazy objects: setRawValueWithoutLazyInitialization() preserves readonly semantics
3--FILE--
4<?php
5
6class C {
7    public function __construct() {
8        try {
9            $this->a = 1;
10        } catch (Error $e) {
11            printf("%s: %s\n", $e::class, $e->getMessage());
12        }
13    }
14    public readonly int $a;
15    public $b;
16}
17
18function test(string $name, object $obj) {
19    printf("# %s\n", $name);
20
21    $reflector = new ReflectionClass(C::class);
22    $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 2);
23
24    var_dump($obj->a);
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
48int(2)
49bool(false)
50lazy ghost object(C)#%d (1) {
51  ["a"]=>
52  int(2)
53}
54Error: Cannot modify readonly property C::$a
55object(C)#%d (2) {
56  ["a"]=>
57  int(2)
58  ["b"]=>
59  NULL
60}
61# Proxy
62int(2)
63bool(false)
64lazy proxy object(C)#%d (1) {
65  ["a"]=>
66  int(2)
67}
68lazy proxy object(C)#%d (1) {
69  ["instance"]=>
70  object(C)#%d (2) {
71    ["a"]=>
72    int(1)
73    ["b"]=>
74    NULL
75  }
76}
77