1--TEST-- 2Lazy objects: Initializer effects are reverted after exception (properties hashtable referenced after initializer) 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 // Builds properties hashtable 20 var_dump(get_mangled_object_vars($obj)); 21 22 try { 23 $reflector->initializeLazyObject($obj); 24 } catch (Exception $e) { 25 printf("%s\n", $e->getMessage()); 26 } 27 28 var_dump($obj); 29 printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); 30 31 var_dump($table); 32} 33 34$reflector = new ReflectionClass(C::class); 35 36$obj = $reflector->newLazyGhost(function ($obj) { 37 global $table; 38 var_dump("initializer"); 39 $obj->a = 3; 40 $obj->b = 4; 41 $obj->c = 5; 42 $table = (array) $obj; 43 throw new Exception('initializer exception'); 44}); 45 46test('Ghost', $obj); 47 48$obj = $reflector->newLazyProxy(function ($obj) { 49 global $table; 50 var_dump("initializer"); 51 $obj->a = 3; 52 $obj->b = 4; 53 $obj->c = 5; 54 $table = (array) $obj; 55 throw new Exception('initializer exception'); 56}); 57 58// Initializer effects on the proxy are not reverted 59test('Proxy', $obj); 60 61--EXPECTF-- 62# Ghost: 63array(1) { 64 ["c"]=> 65 int(0) 66} 67string(11) "initializer" 68initializer exception 69lazy ghost object(C)#%d (1) { 70 ["b"]=> 71 uninitialized(int) 72 ["c"]=> 73 int(0) 74} 75Is lazy: 1 76 77Warning: Undefined variable $table in %s on line %d 78NULL 79# Proxy: 80array(1) { 81 ["c"]=> 82 int(0) 83} 84string(11) "initializer" 85initializer exception 86lazy proxy object(C)#%d (3) { 87 ["a"]=> 88 int(3) 89 ["b"]=> 90 int(4) 91 ["c"]=> 92 int(5) 93} 94Is lazy: 1 95 96Warning: Undefined variable $table in %s on line %d 97NULL 98