1--TEST-- 2ZE2 iterators and break 3--FILE-- 4<?php 5class c_iter implements Iterator { 6 7 private $obj; 8 private $num = 0; 9 10 function __construct($obj) { 11 echo __METHOD__ . "\n"; 12 $this->obj = $obj; 13 } 14 function rewind(): void { 15 echo __METHOD__ . "\n"; 16 $this->num = 0; 17 } 18 function valid(): bool { 19 $more = $this->num < $this->obj->max; 20 echo __METHOD__ . ' = ' .($more ? 'true' : 'false') . "\n"; 21 return $more; 22 } 23 function current(): mixed { 24 echo __METHOD__ . "\n"; 25 return $this->num; 26 } 27 function next(): void { 28 echo __METHOD__ . "\n"; 29 $this->num++; 30 } 31 function key(): mixed { 32 echo __METHOD__ . "\n"; 33 switch($this->num) { 34 case 0: return "1st"; 35 case 1: return "2nd"; 36 case 2: return "3rd"; 37 default: return "???"; 38 } 39 } 40 function __destruct() { 41 echo __METHOD__ . "\n"; 42 } 43} 44 45class c implements IteratorAggregate { 46 47 public $max = 3; 48 49 function getIterator(): Traversable { 50 echo __METHOD__ . "\n"; 51 return new c_iter($this); 52 } 53 function __destruct() { 54 echo __METHOD__ . "\n"; 55 } 56} 57 58$t = new c(); 59 60foreach($t as $k => $v) { 61 foreach($t as $w) { 62 echo "double:$v:$w\n"; 63 break; 64 } 65} 66 67unset($t); 68 69print "Done\n"; 70?> 71--EXPECT-- 72c::getIterator 73c_iter::__construct 74c_iter::rewind 75c_iter::valid = true 76c_iter::current 77c_iter::key 78c::getIterator 79c_iter::__construct 80c_iter::rewind 81c_iter::valid = true 82c_iter::current 83double:0:0 84c_iter::__destruct 85c_iter::next 86c_iter::valid = true 87c_iter::current 88c_iter::key 89c::getIterator 90c_iter::__construct 91c_iter::rewind 92c_iter::valid = true 93c_iter::current 94double:1:0 95c_iter::__destruct 96c_iter::next 97c_iter::valid = true 98c_iter::current 99c_iter::key 100c::getIterator 101c_iter::__construct 102c_iter::rewind 103c_iter::valid = true 104c_iter::current 105double:2:0 106c_iter::__destruct 107c_iter::next 108c_iter::valid = false 109c_iter::__destruct 110c::__destruct 111Done 112