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