1--TEST-- 2Lazy objects: setRawValueWithoutLazyInitialization() leaves property as lazy if exception prevents update 3--FILE-- 4<?php 5 6class C { 7 public function __construct() { 8 printf("%s\n", __METHOD__); 9 } 10 public int $a; 11 public $b; 12} 13 14function test(string $name, object $obj) { 15 printf("# %s\n", $name); 16 17 $reflector = new ReflectionClass(C::class); 18 try { 19 $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); 20 } catch (Error $e) { 21 printf("%s: %s\n", $e::class, $e->getMessage()); 22 } 23 24 // Prop is still lazy: This triggers initialization 25 $obj->a = 1; 26 var_dump(!$reflector->isUninitializedLazyObject($obj)); 27 var_dump($obj); 28} 29 30$reflector = new ReflectionClass(C::class); 31$obj = $reflector->newLazyGhost(function ($obj) { 32 $obj->__construct(); 33}); 34 35test('Ghost', $obj); 36 37$obj = $reflector->newLazyProxy(function () { 38 return new C(); 39}); 40 41test('Proxy', $obj); 42 43?> 44--EXPECTF-- 45# Ghost 46TypeError: Cannot assign stdClass to property C::$a of type int 47C::__construct 48bool(true) 49object(C)#%d (2) { 50 ["a"]=> 51 int(1) 52 ["b"]=> 53 NULL 54} 55# Proxy 56TypeError: Cannot assign stdClass to property C::$a of type int 57C::__construct 58bool(true) 59lazy proxy object(C)#%d (1) { 60 ["instance"]=> 61 object(C)#%d (2) { 62 ["a"]=> 63 int(1) 64 ["b"]=> 65 NULL 66 } 67} 68