php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76765 iterator_apply doesn't work with current() on DoublyLinkedLists
Submitted: 2018-08-19 20:00 UTC Modified: 2018-08-19 21:44 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: tezcatl at fedoraproject dot org Assigned:
Status: Verified Package: SPL related
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
 [2018-08-19 20:00 UTC] tezcatl at fedoraproject dot org
Description:
------------
---
From manual page: http://www.php.net/function.iterator-apply
---
Iteration doesn't work as expected on SplDoublyLinkedList, as if next() was not called while using current() inside the callback passed to iterator_apply

https://3v4l.org/ARLUZ


Test script:
---------------
<?php
$ll = new SplDoublyLinkedList();

$ll->push('one');
$ll->push('two');
$ll->push('three');
$ll->push('four');

$ll->rewind();

$iterations_done = iterator_apply($ll, function(Iterator $it) {
    echo $it->key(),"\t->", $it->current(),"\t->", ucfirst($it->current()),".\n";
    return true;
}, array($ll));
echo "Did iterate {$iterations_done} times \n";

foreach($ll as $key => $value) {
    $uppercase = ucfirst($value);
    echo "{$key}\t->{$value}\t->{$uppercase}.\n";
}

Expected result:
----------------
0	->one	->One.
1	->two	->Two.
2	->three	->Three.
3	->four	->Four.
Did iterate 4 times 
0	->one	->One.
1	->two	->Two.
2	->three	->Three.
3	->four	->Four.

Actual result:
--------------
0	->one	->One.
0	->one	->One.
0	->one	->One.
0	->one	->One.
Did iterate 4 times 
0	->one	->One.
1	->two	->Two.
2	->three	->Three.
3	->four	->Four.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-08-19 21:44 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2018-08-19 21:44 UTC] cmb@php.net
Automatic iteration (foreach, iterator_apply()) on an
SplDoublyLinkedList happens on an external iterator, but
::current() and friends always work on the list directly. Removing
the ::rewind() call, which shouldn't be necessary for
iterator_apply() anyway, yields:

    0       ->      ->.
    0       ->      ->.
    0       ->      ->.
    0       ->      ->.
    Did iterate 4 times

Calling additionally ::next() in the callback brings the desired
results[1].

[1] <https://3v4l.org/ff5j2>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Dec 04 16:01:29 2024 UTC