1--TEST-- 2Lazy objects: fetch ref on 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 public function __construct() { 11 var_dump(__METHOD__); 12 } 13} 14 15function test(string $name, object $obj) { 16 printf("# %s:\n", $name); 17 18 var_dump($obj); 19 $ref = &$obj->a; 20 $ref = &$obj->b; 21 try { 22 $ref = &$obj->c; 23 } catch (Error $e) { 24 printf("%s\n", $e->getMessage()); 25 } 26 var_dump($ref); 27 var_dump($obj); 28} 29 30$reflector = new ReflectionClass(C::class); 31 32$obj = $reflector->newLazyGhost(function ($obj) { 33 var_dump("initializer"); 34 $obj->__construct(); 35}); 36 37test('Ghost', $obj); 38 39$obj = $reflector->newLazyProxy(function ($obj) { 40 var_dump("initializer"); 41 return new C(); 42}); 43 44test('Proxy', $obj); 45 46--EXPECTF-- 47# Ghost: 48lazy ghost object(C)#%d (0) { 49 ["b"]=> 50 uninitialized(int) 51 ["c"]=> 52 uninitialized(int) 53} 54string(11) "initializer" 55string(14) "C::__construct" 56Cannot access uninitialized non-nullable property C::$c by reference 57int(1) 58object(C)#%d (2) { 59 ["a"]=> 60 NULL 61 ["b"]=> 62 &int(1) 63 ["c"]=> 64 uninitialized(int) 65} 66# Proxy: 67lazy proxy object(C)#%d (0) { 68 ["b"]=> 69 uninitialized(int) 70 ["c"]=> 71 uninitialized(int) 72} 73string(11) "initializer" 74string(14) "C::__construct" 75Cannot access uninitialized non-nullable property C::$c by reference 76int(1) 77lazy proxy object(C)#%d (1) { 78 ["instance"]=> 79 object(C)#%d (2) { 80 ["a"]=> 81 NULL 82 ["b"]=> 83 &int(1) 84 ["c"]=> 85 uninitialized(int) 86 } 87} 88