1--TEST-- 2Lazy objects: setRawValueWithoutLazyInitialization() may trigger initialization via side effects (__destruct()) 3--FILE-- 4<?php 5 6class C { 7 public function __construct() { 8 printf("%s\n", __METHOD__); 9 $this->a = 'a'; 10 $this->b = 'b'; 11 } 12 public $a; 13 public $b; 14} 15 16function test(string $name, object $obj) { 17 printf("# %s\n", $name); 18 19 $reflector = new ReflectionClass(C::class); 20 21 $value = new class($obj) { 22 function __construct(public object $obj) {} 23 function __destruct() { 24 $this->obj->b = ''; 25 } 26 }; 27 $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $value); 28 $value = null; 29 30 $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); 31 32 var_dump(!$reflector->isUninitializedLazyObject($obj)); 33 var_dump($obj); 34} 35 36$reflector = new ReflectionClass(C::class); 37$obj = $reflector->newLazyGhost(function ($obj) { 38 $obj->__construct(); 39}); 40 41test('Ghost', $obj); 42 43$obj = $reflector->newLazyProxy(function () { 44 return new C(); 45}); 46 47test('Proxy', $obj); 48 49?> 50--EXPECTF-- 51# Ghost 52C::__construct 53bool(true) 54object(C)#%d (2) { 55 ["a"]=> 56 string(1) "a" 57 ["b"]=> 58 string(0) "" 59} 60# Proxy 61C::__construct 62bool(true) 63lazy proxy object(C)#%d (1) { 64 ["instance"]=> 65 object(C)#%d (2) { 66 ["a"]=> 67 string(1) "a" 68 ["b"]=> 69 string(0) "" 70 } 71} 72