1--TEST-- 2ZE2 iterators and foreach 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->num = 0; 13 $this->obj = $obj; 14 } 15 function rewind(): void { 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 echo __METHOD__ . "\n"; 32 switch($this->num) { 33 case 0: return "1st"; 34 case 1: return "2nd"; 35 case 2: return "3rd"; 36 default: return "???"; 37 } 38 } 39} 40 41class c implements IteratorAggregate { 42 43 public $max = 3; 44 45 function getIterator(): Traversable { 46 echo __METHOD__ . "\n"; 47 return new c_iter($this); 48 } 49} 50 51echo "===Array===\n"; 52 53$a = array(0,1,2); 54foreach($a as $v) { 55 echo "array:$v\n"; 56} 57 58echo "===Manual===\n"; 59$t = new c(); 60for ($iter = $t->getIterator(); $iter->valid(); $iter->next()) { 61 echo $iter->current() . "\n"; 62} 63 64echo "===foreach/std===\n"; 65foreach($t as $v) { 66 echo "object:$v\n"; 67} 68 69echo "===foreach/rec===\n"; 70foreach($t as $v) { 71 foreach($t as $w) { 72 echo "double:$v:$w\n"; 73 } 74} 75 76echo "===foreach/key===\n"; 77foreach($t as $i => $v) { 78 echo "object:$i=>$v\n"; 79} 80 81print "Done\n"; 82exit(0); 83?> 84--EXPECT-- 85===Array=== 86array:0 87array:1 88array:2 89===Manual=== 90c::getIterator 91c_iter::__construct 92c_iter::valid = true 93c_iter::current 940 95c_iter::next 96c_iter::valid = true 97c_iter::current 981 99c_iter::next 100c_iter::valid = true 101c_iter::current 1022 103c_iter::next 104c_iter::valid = false 105===foreach/std=== 106c::getIterator 107c_iter::__construct 108c_iter::valid = true 109c_iter::current 110object:0 111c_iter::next 112c_iter::valid = true 113c_iter::current 114object:1 115c_iter::next 116c_iter::valid = true 117c_iter::current 118object:2 119c_iter::next 120c_iter::valid = false 121===foreach/rec=== 122c::getIterator 123c_iter::__construct 124c_iter::valid = true 125c_iter::current 126c::getIterator 127c_iter::__construct 128c_iter::valid = true 129c_iter::current 130double:0:0 131c_iter::next 132c_iter::valid = true 133c_iter::current 134double:0:1 135c_iter::next 136c_iter::valid = true 137c_iter::current 138double:0:2 139c_iter::next 140c_iter::valid = false 141c_iter::next 142c_iter::valid = true 143c_iter::current 144c::getIterator 145c_iter::__construct 146c_iter::valid = true 147c_iter::current 148double:1:0 149c_iter::next 150c_iter::valid = true 151c_iter::current 152double:1:1 153c_iter::next 154c_iter::valid = true 155c_iter::current 156double:1:2 157c_iter::next 158c_iter::valid = false 159c_iter::next 160c_iter::valid = true 161c_iter::current 162c::getIterator 163c_iter::__construct 164c_iter::valid = true 165c_iter::current 166double:2:0 167c_iter::next 168c_iter::valid = true 169c_iter::current 170double:2:1 171c_iter::next 172c_iter::valid = true 173c_iter::current 174double:2:2 175c_iter::next 176c_iter::valid = false 177c_iter::next 178c_iter::valid = false 179===foreach/key=== 180c::getIterator 181c_iter::__construct 182c_iter::valid = true 183c_iter::current 184c_iter::key 185object:1st=>0 186c_iter::next 187c_iter::valid = true 188c_iter::current 189c_iter::key 190object:2nd=>1 191c_iter::next 192c_iter::valid = true 193c_iter::current 194c_iter::key 195object:3rd=>2 196c_iter::next 197c_iter::valid = false 198Done 199