1--TEST-- 2Lazy objects: fetch skipped property does not initialize object 3--FILE-- 4<?php 5 6class C { 7 public $a; 8 public int $b = 1; 9 public int $c; 10 11 public function __construct(int $a) { 12 var_dump(__METHOD__); 13 $this->a = $a; 14 $this->b = 2; 15 } 16} 17 18function test(string $name, object $obj) { 19 printf("# %s:\n", $name); 20 21 $reflector = new ReflectionClass($obj); 22 $reflector->getProperty('a')->skipLazyInitialization($obj); 23 $reflector->getProperty('b')->skipLazyInitialization($obj); 24 $reflector->getProperty('c')->skipLazyInitialization($obj); 25 26 var_dump($obj); 27 var_dump($obj->a); 28 var_dump($obj->b); 29 try { 30 var_dump($obj->c); 31 } catch (Error $e) { 32 printf("%s\n", $e->getMessage()); 33 } 34 var_dump($obj); 35} 36 37$reflector = new ReflectionClass(C::class); 38 39$obj = $reflector->newLazyGhost(function ($obj) { 40 var_dump("initializer"); 41 $obj->__construct(1); 42}); 43 44test('Ghost', $obj); 45 46$obj = $reflector->newLazyProxy(function ($obj) { 47 var_dump("initializer"); 48 return new C(1); 49}); 50 51test('Proxy', $obj); 52 53--EXPECTF-- 54# Ghost: 55object(C)#%d (2) { 56 ["a"]=> 57 NULL 58 ["b"]=> 59 int(1) 60 ["c"]=> 61 uninitialized(int) 62} 63NULL 64int(1) 65Typed property C::$c must not be accessed before initialization 66object(C)#%d (2) { 67 ["a"]=> 68 NULL 69 ["b"]=> 70 int(1) 71 ["c"]=> 72 uninitialized(int) 73} 74# Proxy: 75object(C)#%d (2) { 76 ["a"]=> 77 NULL 78 ["b"]=> 79 int(1) 80 ["c"]=> 81 uninitialized(int) 82} 83NULL 84int(1) 85Typed property C::$c must not be accessed before initialization 86object(C)#%d (2) { 87 ["a"]=> 88 NULL 89 ["b"]=> 90 int(1) 91 ["c"]=> 92 uninitialized(int) 93} 94