xref: /PHP-8.3/ext/spl/tests/iterator_022.phpt (revision b3e08881)
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