Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Like by the name of the class alone (<code>NoRewindIterator</code>), <a href="http://php.net/NoRewindIterator" rel="nofollow noreferrer">the manual has</a> the following wording in specific:</p> <blockquote> <p>NoRewindIterator - This iterator cannot be rewound.</p> </blockquote> <p>And for the concrete method:</p> <blockquote> <p>NoRewindIterator::rewind() - Prevents the rewind operation on the inner iterator.</p> </blockquote> <p>This implies that the <code>Iterator::rewind()</code> method is not passed through to the inner iterator. Tests also show this, here is a simple one I've been running (code of all iterators not part of PHP are in the <a href="https://github.com/hakre/Iterator-Garden" rel="nofollow noreferrer">Iterator Garden</a>):</p> <pre><code>$iterator = new RangeIterator(1, 1); $debug = new DebugIteratorDecorator($iterator); $noRewind = new NoRewindIterator($debug); echo "first foreach:\n"; foreach ($noRewind as $value) { echo "iteration value: $value\n"; } </code></pre> <p>In this code, the debug-iterator prints (echoes) iteration information on the fly:</p> <pre><code>first foreach: Iterating (RangeIterator): #0 valid() Iterating (RangeIterator): #0 parent::valid() is TRUE Iterating (RangeIterator): #0 current() Iterating (RangeIterator): #0 parent::current() is 1 iteration value: 1 Iterating (RangeIterator): #1 next() Iterating (RangeIterator): #1 after parent::next() Iterating (RangeIterator): #1 valid() Iterating (RangeIterator): #1 parent::valid() is FALSE </code></pre> <p>As this shows, <code>$iterator-&gt;rewind()</code> is never called.</p> <p>This also makes sense for the same reasons given in a related question: <a href="https://stackoverflow.com/q/2458955/367456"><em>Why must I rewind IteratorIterator</em></a>. The <code>NoRewindIterator</code> extends from <code>IteratorIterator</code> and <em>different</em> to it's parent class, the <code>getInnerIterator()</code> method returns an <code>Iterator</code> and not a <code>Traversable</code>.</p> <p>This change allows you to initialize the rewind when you need to:</p> <pre><code>echo "\n\$calling noRewind-&gt;getInnerIterator()-&gt;rewind():\n"; $noRewind-&gt;getInnerIterator()-&gt;rewind(); echo "\nsecond foreach:\n"; foreach ($noRewind as $value) { echo "iteration value: $value\n"; } </code></pre> <p>Exemplary debug output again:</p> <pre><code>$calling noRewind-&gt;getInnerIterator()-&gt;rewind(): Iterating (RangeIterator): #0 rewind() Iterating (RangeIterator): #0 after parent::rewind() second foreach: Iterating (RangeIterator): #0 valid() Iterating (RangeIterator): #0 parent::valid() is TRUE Iterating (RangeIterator): #0 current() Iterating (RangeIterator): #0 parent::current() is 1 iteration value: 1 Iterating (RangeIterator): #1 next() Iterating (RangeIterator): #1 after parent::next() Iterating (RangeIterator): #1 valid() Iterating (RangeIterator): #1 parent::valid() is FALSE </code></pre> <p>Knowing about these details then does allow to create a <code>OneTimeRewindIterator</code> for example:</p> <pre><code>/** * Class OneTimeRewindIterator */ class OneTimeRewindIterator extends NoRewindIterator { private $didRewind = FALSE; public function rewind() { if ($this-&gt;didRewind) return; $this-&gt;didRewind = TRUE; $this-&gt;getInnerIterator()-&gt;rewind(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload