1--TEST-- 2Lazy objects: virtual hooked property fetch may initialize object if hook observes object state 3--FILE-- 4<?php 5 6class C { 7 public $_a; 8 public $a { 9 &get { return $this->_a; } 10 } 11 public int $b = 1; 12 13 public function __construct(int $a) { 14 var_dump(__METHOD__); 15 $this->_a = $a; 16 $this->b = 2; 17 } 18} 19 20function test(string $name, object $obj) { 21 printf("# %s:\n", $name); 22 23 var_dump($obj); 24 $a = &$obj->a; 25 var_dump($a); 26 var_dump($obj); 27} 28 29$reflector = new ReflectionClass(C::class); 30 31$obj = $reflector->newLazyGhost(function ($obj) { 32 var_dump("initializer"); 33 $obj->__construct(1); 34}); 35 36test('Ghost', $obj); 37 38$obj = $reflector->newLazyProxy(function ($obj) { 39 var_dump("initializer"); 40 return new C(1); 41}); 42 43test('Proxy', $obj); 44 45--EXPECTF-- 46# Ghost: 47lazy ghost object(C)#%d (0) { 48 ["b"]=> 49 uninitialized(int) 50} 51string(11) "initializer" 52string(14) "C::__construct" 53int(1) 54object(C)#%d (2) { 55 ["_a"]=> 56 &int(1) 57 ["b"]=> 58 int(2) 59} 60# Proxy: 61lazy proxy object(C)#%d (0) { 62 ["b"]=> 63 uninitialized(int) 64} 65string(11) "initializer" 66string(14) "C::__construct" 67int(1) 68lazy proxy object(C)#%d (1) { 69 ["instance"]=> 70 object(C)#%d (2) { 71 ["_a"]=> 72 &int(1) 73 ["b"]=> 74 int(2) 75 } 76} 77