1--TEST-- 2Lazy objects: write to 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() { 12 var_dump(__METHOD__); 13 } 14} 15 16function test(string $name, object $obj) { 17 printf("# %s:\n", $name); 18 19 $reflector = new ReflectionClass(C::class); 20 $reflector->getProperty('a')->skipLazyInitialization($obj); 21 $reflector->getProperty('b')->skipLazyInitialization($obj); 22 $reflector->getProperty('c')->skipLazyInitialization($obj); 23 24 var_dump($obj); 25 $obj->a = 2; 26 $obj->b = 2; 27 $obj->c = 2; 28 var_dump($obj); 29} 30 31$reflector = new ReflectionClass(C::class); 32 33$obj = $reflector->newLazyGhost(function ($obj) { 34 var_dump("initializer"); 35 $obj->__construct(); 36}); 37 38test('Ghost', $obj); 39 40$obj = $reflector->newLazyProxy(function ($obj) { 41 var_dump("initializer"); 42 return new C(); 43}); 44 45test('Proxy', $obj); 46 47--EXPECTF-- 48# Ghost: 49object(C)#%d (2) { 50 ["a"]=> 51 NULL 52 ["b"]=> 53 int(1) 54 ["c"]=> 55 uninitialized(int) 56} 57object(C)#%d (3) { 58 ["a"]=> 59 int(2) 60 ["b"]=> 61 int(2) 62 ["c"]=> 63 int(2) 64} 65# Proxy: 66object(C)#%d (2) { 67 ["a"]=> 68 NULL 69 ["b"]=> 70 int(1) 71 ["c"]=> 72 uninitialized(int) 73} 74object(C)#%d (3) { 75 ["a"]=> 76 int(2) 77 ["b"]=> 78 int(2) 79 ["c"]=> 80 int(2) 81} 82