1--TEST-- 2Lazy objects: Foreach initializes object 3--FILE-- 4<?php 5 6class C { 7 public int $a; 8 public int $b; 9 public function __construct() { 10 var_dump(__METHOD__); 11 $this->a = 1; 12 $this->b = 2; 13 } 14} 15 16$reflector = new ReflectionClass(C::class); 17 18print "# Ghost:\n"; 19 20$obj = $reflector->newLazyGhost(function ($obj) { 21 var_dump("initializer"); 22 $obj->__construct(); 23}); 24 25foreach ($obj as $prop => $value) { 26 var_dump($prop, $value); 27} 28 29print "# Ghost (by ref):\n"; 30 31$obj = $reflector->newLazyGhost(function ($obj) { 32 var_dump("initializer"); 33 $obj->__construct(); 34}); 35 36foreach ($obj as $prop => &$value) { 37 var_dump($prop, $value); 38} 39 40print "# Proxy:\n"; 41 42$obj = $reflector->newLazyProxy(function ($obj) { 43 var_dump("initializer"); 44 return new C(); 45}); 46 47foreach ($obj as $prop => $value) { 48 var_dump($prop, $value); 49} 50 51print "# Proxy (by ref):\n"; 52 53$obj = $reflector->newLazyProxy(function ($obj) { 54 var_dump("initializer"); 55 return new C(); 56}); 57 58foreach ($obj as $prop => &$value) { 59 var_dump($prop, $value); 60} 61 62print "# Ghost (init failure)\n"; 63 64$fail = true; 65$obj = $reflector->newLazyGhost(function ($obj) use (&$fail) { 66 if ($fail) { 67 throw new Exception("initializer"); 68 } else { 69 var_dump("initializer"); 70 $obj->__construct(); 71 } 72}); 73 74try { 75 foreach ($obj as $prop => $value) { 76 var_dump($prop, $value); 77 } 78} catch (Exception $e) { 79 printf("%s: %s\n", $e::class, $e->getMessage()); 80} 81 82$fail = false; 83foreach ($obj as $prop => $value) { 84 var_dump($prop, $value); 85} 86 87print "# Ghost (init failure, by ref)\n"; 88 89$fail = true; 90$obj = $reflector->newLazyGhost(function ($obj) use (&$fail) { 91 if ($fail) { 92 throw new Exception("initializer"); 93 } else { 94 var_dump("initializer"); 95 $obj->__construct(); 96 } 97}); 98 99try { 100 foreach ($obj as $prop => &$value) { 101 var_dump($prop, $value); 102 } 103} catch (Exception $e) { 104 printf("%s: %s\n", $e::class, $e->getMessage()); 105} 106 107$fail = false; 108foreach ($obj as $prop => &$value) { 109 var_dump($prop, $value); 110} 111 112?> 113--EXPECT-- 114# Ghost: 115string(11) "initializer" 116string(14) "C::__construct" 117string(1) "a" 118int(1) 119string(1) "b" 120int(2) 121# Ghost (by ref): 122string(11) "initializer" 123string(14) "C::__construct" 124string(1) "a" 125int(1) 126string(1) "b" 127int(2) 128# Proxy: 129string(11) "initializer" 130string(14) "C::__construct" 131string(1) "a" 132int(1) 133string(1) "b" 134int(2) 135# Proxy (by ref): 136string(11) "initializer" 137string(14) "C::__construct" 138string(1) "a" 139int(1) 140string(1) "b" 141int(2) 142# Ghost (init failure) 143Exception: initializer 144string(11) "initializer" 145string(14) "C::__construct" 146string(1) "a" 147int(1) 148string(1) "b" 149int(2) 150# Ghost (init failure, by ref) 151Exception: initializer 152string(11) "initializer" 153string(14) "C::__construct" 154string(1) "a" 155int(1) 156string(1) "b" 157int(2) 158