1--TEST-- 2foreach with nested iteratorAggregates 3--FILE-- 4<?php 5class EnglishMealIterator implements Iterator { 6 private $pos=0; 7 private $myContent=array("breakfast", "dinner", "tea"); 8 9 public function valid(): bool { 10 global $indent; 11 echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; 12 return $this->pos<3; 13 } 14 15 public function next(): void { 16 global $indent; 17 echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; 18 $this->myContent[$this->pos++]; 19 } 20 21 public function rewind(): void { 22 global $indent; 23 echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; 24 $this->pos=0; 25 } 26 27 public function current(): mixed { 28 global $indent; 29 echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; 30 return $this->myContent[$this->pos]; 31 } 32 33 public function key(): mixed { 34 global $indent; 35 echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; 36 return "meal " . $this->pos; 37 } 38 39} 40 41class A1 implements IteratorAggregate { 42 function getIterator(): Traversable { 43 return new EnglishMealIterator; 44 } 45} 46 47class A2 implements IteratorAggregate { 48 function getIterator(): Traversable { 49 return new A1; 50 } 51} 52 53class A3 implements IteratorAggregate { 54 function getIterator(): Traversable { 55 return new A2; 56 } 57} 58 59echo "\n-----( A1: )-----\n"; 60foreach (new A1 as $k=>$v) { 61 echo "$k => $v\n"; 62} 63 64echo "\n-----( A2: )-----\n"; 65foreach (new A2 as $k=>$v) { 66 echo "$k => $v\n"; 67} 68 69echo "\n-----( A3: )-----\n"; 70foreach (new A3 as $k=>$v) { 71 echo "$k => $v\n"; 72} 73 74?> 75--EXPECT-- 76-----( A1: )----- 77--> EnglishMealIterator::rewind (0) 78--> EnglishMealIterator::valid (0) 79--> EnglishMealIterator::current (0) 80--> EnglishMealIterator::key (0) 81meal 0 => breakfast 82--> EnglishMealIterator::next (0) 83--> EnglishMealIterator::valid (1) 84--> EnglishMealIterator::current (1) 85--> EnglishMealIterator::key (1) 86meal 1 => dinner 87--> EnglishMealIterator::next (1) 88--> EnglishMealIterator::valid (2) 89--> EnglishMealIterator::current (2) 90--> EnglishMealIterator::key (2) 91meal 2 => tea 92--> EnglishMealIterator::next (2) 93--> EnglishMealIterator::valid (3) 94 95-----( A2: )----- 96--> EnglishMealIterator::rewind (0) 97--> EnglishMealIterator::valid (0) 98--> EnglishMealIterator::current (0) 99--> EnglishMealIterator::key (0) 100meal 0 => breakfast 101--> EnglishMealIterator::next (0) 102--> EnglishMealIterator::valid (1) 103--> EnglishMealIterator::current (1) 104--> EnglishMealIterator::key (1) 105meal 1 => dinner 106--> EnglishMealIterator::next (1) 107--> EnglishMealIterator::valid (2) 108--> EnglishMealIterator::current (2) 109--> EnglishMealIterator::key (2) 110meal 2 => tea 111--> EnglishMealIterator::next (2) 112--> EnglishMealIterator::valid (3) 113 114-----( A3: )----- 115--> EnglishMealIterator::rewind (0) 116--> EnglishMealIterator::valid (0) 117--> EnglishMealIterator::current (0) 118--> EnglishMealIterator::key (0) 119meal 0 => breakfast 120--> EnglishMealIterator::next (0) 121--> EnglishMealIterator::valid (1) 122--> EnglishMealIterator::current (1) 123--> EnglishMealIterator::key (1) 124meal 1 => dinner 125--> EnglishMealIterator::next (1) 126--> EnglishMealIterator::valid (2) 127--> EnglishMealIterator::current (2) 128--> EnglishMealIterator::key (2) 129meal 2 => tea 130--> EnglishMealIterator::next (2) 131--> EnglishMealIterator::valid (3) 132