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