1--TEST-- 2SPL: RecursiveIteratorIterator and callHasChildren/callGetChildren 3--FILE-- 4<?php 5 6class MyRecursiveArrayIterator extends RecursiveArrayIterator 7{ 8 function getChildren(): ?RecursiveArrayIterator 9 { 10 echo __METHOD__ . "\n"; 11 return $this->current(); 12 } 13 14 function valid(): bool 15 { 16 if (!parent::valid()) 17 { 18 echo __METHOD__ . " = false\n"; 19 return false; 20 } 21 else 22 { 23 return true; 24 } 25 } 26} 27 28class RecursiveArrayIteratorIterator extends RecursiveIteratorIterator 29{ 30 private $max_depth; 31 private $over = 0; 32 private $skip = false; 33 34 function __construct($it, $max_depth) 35 { 36 $this->max_depth = $max_depth; 37 parent::__construct($it); 38 } 39 40 function rewind(): void 41 { 42 echo __METHOD__ . "\n"; 43 $this->skip = false; 44 parent::rewind(); 45 } 46 47 function valid(): bool 48 { 49 echo __METHOD__ . "\n"; 50 if ($this->skip) 51 { 52 $this->skip = false; 53 $this->next(); 54 } 55 return parent::valid(); 56 } 57 58 function current(): mixed 59 { 60 echo __METHOD__ . "\n"; 61 return parent::current(); 62 } 63 64 function key(): int 65 { 66 echo __METHOD__ . "\n"; 67 return parent::key(); 68 } 69 70 function next(): void 71 { 72 echo __METHOD__ . "\n"; 73 parent::next(); 74 } 75 76 function callHasChildren(): bool 77 { 78 $this->skip = false; 79 $has = parent::callHasChildren(); 80 $res = $this->getDepth() < $this->max_depth && $has; 81 echo __METHOD__ . "(".$this->getDepth().") = ".($res?"yes":"no")."/".($has?"yes":"no")."\n"; 82 if ($has && !$res) 83 { 84 $this->over++; 85 if ($this->over == 2) { 86 $this->skip = true; 87 } 88 } 89 return $res; 90 } 91 92 function callGetChildren(): ?MyRecursiveArrayIterator 93 { 94 if ($this->over == 2) 95 { 96 echo __METHOD__ . "(skip)\n"; 97 return NULL; 98 } 99 echo __METHOD__ . "(ok:{$this->over})\n"; 100 return new MyRecursiveArrayIterator($this->current()); 101 } 102 103 function beginChildren(): void 104 { 105 echo __METHOD__ . "(".$this->getDepth().")\n"; 106 } 107 108 function endChildren(): void 109 { 110 echo __METHOD__ . "(".$this->getDepth().")\n"; 111 } 112} 113 114try 115{ 116 foreach(new RecursiveArrayIteratorIterator(new MyRecursiveArrayIterator(array("a", array("ba", array("bba", "bbb"), array(array("bcaa"), array("bcba"))), array("ca"), "d")), 2) as $k=>$v) 117 { 118 if (is_array($v)) $v = join('',$v); 119 echo "$k=>$v\n"; 120 } 121} 122catch(UnexpectedValueException $e) 123{ 124 echo $e->getMessage() . "\n"; 125} 126 127?> 128--EXPECT-- 129RecursiveArrayIteratorIterator::rewind 130RecursiveArrayIteratorIterator::callHasChildren(0) = no/no 131RecursiveArrayIteratorIterator::valid 132RecursiveArrayIteratorIterator::current 133RecursiveArrayIteratorIterator::key 1340=>a 135RecursiveArrayIteratorIterator::next 136RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes 137RecursiveArrayIteratorIterator::callGetChildren(ok:0) 138RecursiveArrayIteratorIterator::current 139RecursiveArrayIteratorIterator::beginChildren(1) 140RecursiveArrayIteratorIterator::callHasChildren(1) = no/no 141RecursiveArrayIteratorIterator::valid 142RecursiveArrayIteratorIterator::current 143RecursiveArrayIteratorIterator::key 1440=>ba 145RecursiveArrayIteratorIterator::next 146RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes 147RecursiveArrayIteratorIterator::callGetChildren(ok:0) 148RecursiveArrayIteratorIterator::current 149RecursiveArrayIteratorIterator::beginChildren(2) 150RecursiveArrayIteratorIterator::callHasChildren(2) = no/no 151RecursiveArrayIteratorIterator::valid 152RecursiveArrayIteratorIterator::current 153RecursiveArrayIteratorIterator::key 1540=>bba 155RecursiveArrayIteratorIterator::next 156RecursiveArrayIteratorIterator::callHasChildren(2) = no/no 157RecursiveArrayIteratorIterator::valid 158RecursiveArrayIteratorIterator::current 159RecursiveArrayIteratorIterator::key 1601=>bbb 161RecursiveArrayIteratorIterator::next 162MyRecursiveArrayIterator::valid = false 163RecursiveArrayIteratorIterator::endChildren(2) 164RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes 165RecursiveArrayIteratorIterator::callGetChildren(ok:0) 166RecursiveArrayIteratorIterator::current 167RecursiveArrayIteratorIterator::beginChildren(2) 168RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes 169RecursiveArrayIteratorIterator::valid 170RecursiveArrayIteratorIterator::current 171RecursiveArrayIteratorIterator::key 1720=>bcaa 173RecursiveArrayIteratorIterator::next 174RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes 175RecursiveArrayIteratorIterator::valid 176RecursiveArrayIteratorIterator::next 177MyRecursiveArrayIterator::valid = false 178RecursiveArrayIteratorIterator::endChildren(2) 179MyRecursiveArrayIterator::valid = false 180RecursiveArrayIteratorIterator::endChildren(1) 181RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes 182RecursiveArrayIteratorIterator::callGetChildren(skip) 183Objects returned by RecursiveIterator::getChildren() must implement RecursiveIterator 184