|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-12-21 02:17 UTC] sixd@php.net
Description:
------------
SPL's InfiniteIterator returns NULL for the first access, unless used in a
'foreach' loop, or a rewind is done.
This means that an explicit rewind is needed before an InfiniteIterator can be
safely be used in an application.
Test script:
---------------
<?php
$b = array('one', 'two', 'three');
$b_it = new InfiniteIterator(new ArrayIterator($b));
for ($i = 0; $i < 7; $i++) {
var_dump($b_it->current());
$b_it->next();
}
?>
Expected result:
----------------
string(3) "one"
string(3) "two"
string(5) "three"
string(3) "one"
string(3) "two"
string(5) "three"
string(3) "one"
Actual result:
--------------
NULL
string(3) "two"
string(5) "three"
string(3) "one"
string(3) "two"
string(5) "three"
string(3) "one"
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 07 16:00:02 2025 UTC |
A bigger example is: <?php echo "'foreach' on ArrayIterator\n"; $c = array('one', 'two', 'three'); $c_it = new ArrayIterator($c); foreach ($c_it as $key => $val) { var_dump($val); } echo "\n'foreach' on InfiniteIterator\n"; $a = array('one', 'two', 'three'); $a_it = new InfiniteIterator(new ArrayIterator($a)); $i = 0; foreach ($a_it as $key => $val) { if ($i++ >= 7) break; var_dump($val); } echo "\n'for' on ArrayIterator\n"; $d = array('one', 'two', 'three'); $d_it = new ArrayIterator($d); for ($i = 0; $i < 3; $i++) { var_dump($d_it->current()); $d_it->next(); } echo "\n'for' on InfiniteIterator\n"; $b = array('one', 'two', 'three'); $b_it = new InfiniteIterator(new ArrayIterator($b)); for ($i = 0; $i < 7; $i++) { var_dump($b_it->current()); $b_it->next(); } ?> This outputs: 'foreach' on ArrayIterator string(3) "one" string(3) "two" string(5) "three" 'foreach' on InfiniteIterator string(3) "one" string(3) "two" string(5) "three" string(3) "one" string(3) "two" string(5) "three" string(3) "one" 'for' on ArrayIterator string(3) "one" string(3) "two" string(5) "three" 'for' on InfiniteIterator NULL string(3) "two" string(5) "three" string(3) "one" string(3) "two" string(5) "three" string(3) "one" So the odd behavior is with the last loop. A "real" life script (from discussion on php.internals) is: <?php // Replacing words in a string with a sequential, repeating set of replacement words $replacements = array('one', 'two', 'three'); $replacements_iterator = new InfiniteIterator(new ArrayIterator($replacements)); $replacements_iterator->rewind(); // why is the rewind needed? $result = preg_replace_callback( '/word/', function($matches) use ($replacements_iterator) { $r = $replacements_iterator->current(); $replacements_iterator->next(); return $r; }, 'word word word word word' ); var_dump($result); // Outputs: // string(21) "one two three one two" // Without the call to $replacements_iterator->rewind(), the output is: // string(18) " two three one two" ?>