1--TEST-- 2Lazy objects: Object is not lazy anymore if all props have been assigned a value (overridden prop) 3--FILE-- 4<?php 5 6class B { 7 public readonly string $b; 8 9 public function __construct() { 10 $this->b = 'b'; 11 } 12} 13 14class C extends B { 15 public string $a; 16 public readonly string $b; 17 18 public function __construct() { 19 parent::__construct(); 20 $this->a = 'a'; 21 } 22} 23 24function test(string $name, object $obj) { 25 $reflector = new ReflectionClass(C::class); 26 27 printf("# %s:\n", $name); 28 29 var_dump(!$reflector->isUninitializedLazyObject($obj)); 30 31 $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); 32 var_dump(!$reflector->isUninitializedLazyObject($obj)); 33 34 // Should not count a second prop initialization 35 $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a2'); 36 var_dump(!$reflector->isUninitializedLazyObject($obj)); 37 38 try { 39 // Should not count a prop initialization 40 $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); 41 } catch (Error $e) { 42 printf("%s: %s\n", $e::class, $e->getMessage()); 43 } 44 45 (new ReflectionProperty(B::class, 'b'))->setRawValueWithoutLazyInitialization($obj, 'b'); 46 var_dump(!$reflector->isUninitializedLazyObject($obj)); 47 48 var_dump($obj); 49} 50 51$reflector = new ReflectionClass(C::class); 52 53$obj = $reflector->newLazyGhost(function ($obj) { 54 var_dump("initializer"); 55 $obj->__construct(); 56}); 57 58test('Ghost', $obj); 59 60$obj = $reflector->newLazyProxy(function ($obj) { 61 var_dump("initializer"); 62 return new C(); 63}); 64 65test('Proxy', $obj); 66 67--EXPECTF-- 68# Ghost: 69bool(false) 70bool(false) 71bool(false) 72TypeError: Cannot assign stdClass to property C::$a of type string 73bool(true) 74object(C)#%d (2) { 75 ["b"]=> 76 string(1) "b" 77 ["a"]=> 78 string(2) "a2" 79} 80# Proxy: 81bool(false) 82bool(false) 83bool(false) 84TypeError: Cannot assign stdClass to property C::$a of type string 85bool(true) 86object(C)#%d (2) { 87 ["b"]=> 88 string(1) "b" 89 ["a"]=> 90 string(2) "a2" 91} 92