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