1--TEST-- 2Lazy objects: Initializer effects are reverted after exception 3--FILE-- 4<?php 5 6class C { 7 public $a = 1; 8 public int $b = 2; 9 public int $c; 10} 11 12function test(string $name, object $obj) { 13 $reflector = new ReflectionClass(C::class); 14 15 printf("# %s:\n", $name); 16 17 (new ReflectionProperty(C::class, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); 18 19 try { 20 $reflector->initializeLazyObject($obj); 21 } catch (Exception $e) { 22 printf("%s\n", $e->getMessage()); 23 } 24 25 var_dump($obj); 26 printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); 27} 28 29$reflector = new ReflectionClass(C::class); 30 31$obj = $reflector->newLazyGhost(function ($obj) { 32 var_dump("initializer"); 33 $obj->a = 3; 34 $obj->b = 4; 35 $obj->c = 5; 36 throw new Exception('initializer exception'); 37}); 38 39test('Ghost', $obj); 40 41$obj = $reflector->newLazyProxy(function ($obj) { 42 var_dump("initializer"); 43 $obj->a = 3; 44 $obj->b = 4; 45 $obj->c = 5; 46 throw new Exception('initializer exception'); 47}); 48 49// Initializer effects on the proxy are not reverted 50test('Proxy', $obj); 51 52--EXPECTF-- 53# Ghost: 54string(11) "initializer" 55initializer exception 56lazy ghost object(C)#%d (1) { 57 ["b"]=> 58 uninitialized(int) 59 ["c"]=> 60 int(0) 61} 62Is lazy: 1 63# Proxy: 64string(11) "initializer" 65initializer exception 66lazy proxy object(C)#%d (3) { 67 ["a"]=> 68 int(3) 69 ["b"]=> 70 int(4) 71 ["c"]=> 72 int(5) 73} 74Is lazy: 1 75