1--TEST-- 2Lazy objects: Object is not lazy anymore if all props have been skipped 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')->skipLazyInitialization($obj); 33 var_dump(!$reflector->isUninitializedLazyObject($obj)); 34 35 // Should not count a second prop initialization 36 $reflector->getProperty('a')->skipLazyInitialization($obj); 37 var_dump(!$reflector->isUninitializedLazyObject($obj)); 38 39 try { 40 // Should not count a prop initialization 41 $reflector->getProperty('xxx')->skipLazyInitialization($obj); 42 } catch (ReflectionException $e) { 43 printf("%s: %s\n", $e::class, $e->getMessage()); 44 } 45 46 try { 47 // Should not count a prop initialization 48 $reflector->getProperty('b')->skipLazyInitialization($obj); 49 } catch (ReflectionException $e) { 50 printf("%s: %s\n", $e::class, $e->getMessage()); 51 } 52 53 (new ReflectionProperty(B::class, 'b'))->skipLazyInitialization($obj); 54 var_dump(!$reflector->isUninitializedLazyObject($obj)); 55 56 var_dump($obj); 57} 58 59$reflector = new ReflectionClass(C::class); 60 61$obj = $reflector->newLazyGhost(function ($obj) { 62 var_dump("initializer"); 63 $obj->__construct(); 64}); 65 66test('Ghost', $obj); 67 68$obj = $reflector->newLazyProxy(function ($obj) { 69 var_dump("initializer"); 70 return new C(); 71}); 72 73test('Proxy', $obj); 74 75--EXPECTF-- 76# Ghost: 77bool(false) 78bool(false) 79bool(false) 80ReflectionException: Property C::$xxx does not exist 81ReflectionException: Property C::$b does not exist 82bool(true) 83object(C)#%d (0) { 84 ["b":"B":private]=> 85 uninitialized(string) 86 ["a"]=> 87 uninitialized(string) 88} 89# Proxy: 90bool(false) 91bool(false) 92bool(false) 93ReflectionException: Property C::$xxx does not exist 94ReflectionException: Property C::$b does not exist 95bool(true) 96object(C)#%d (0) { 97 ["b":"B":private]=> 98 uninitialized(string) 99 ["a"]=> 100 uninitialized(string) 101} 102