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