1--TEST-- 2Iterator exceptions in foreach by reference 3--FILE-- 4<?php 5class IT extends ArrayIterator { 6 private $n = 0; 7 8 function __construct($trap = null) { 9 parent::__construct([0, 1]); 10 $this->trap = $trap; 11 } 12 13 function trap($trap) { 14 if ($trap === $this->trap) { 15 throw new Exception($trap); 16 } 17 } 18 19 function rewind(): void {$this->trap(__FUNCTION__); parent::rewind();} 20 function valid(): bool {$this->trap(__FUNCTION__); return parent::valid();} 21 function key(): string|int|null { $this->trap(__FUNCTION__); return parent::key(); } 22 function next(): void {$this->trap(__FUNCTION__); parent::next();} 23} 24 25foreach(['rewind', 'valid', 'key', 'next'] as $trap) { 26 $obj = new IT($trap); 27 try { 28 // IS_CV 29 foreach ($obj as $key => &$val) echo "$val\n"; 30 } catch (Exception $e) { 31 echo $e->getMessage() . "\n"; 32 } 33 unset($obj); 34 35 try { 36 // IS_VAR 37 foreach (new IT($trap) as $key => &$val) echo "$val\n"; 38 } catch (Exception $e) { 39 echo $e->getMessage() . "\n"; 40 } 41 42 try { 43 // IS_TMP_VAR 44 foreach ((object)new IT($trap) as $key => &$val) echo "$val\n"; 45 } catch (Exception $e) { 46 echo $e->getMessage() . "\n"; 47 } 48} 49?> 50--EXPECT-- 51rewind 52rewind 53rewind 54valid 55valid 56valid 57key 58key 59key 600 61next 620 63next 640 65next 66