php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79404 Referencing to SplFixedArray interrupts foreach loop
Submitted: 2020-03-22 14:44 UTC Modified: 2021-01-08 15:28 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: vlad dot turchinskiy at yandex dot ru Assigned: cmb (profile)
Status: Closed Package: SPL related
PHP Version: 5.4.0 - 7.4.4 OS: all
Private report: No CVE-ID: None
 [2020-03-22 14:44 UTC] vlad dot turchinskiy at yandex dot ru
Description:
------------
Referencing to SplFixedArray interrupts foreach loop.

Test script:
---------------
https://3v4l.org/FdN4i

Expected result:
----------------
3 iterations executed.

Actual result:
--------------
1 iteration executed.

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-03-22 15:37 UTC] vlad dot turchinskiy at yandex dot ru
-Package: SPL_Types +Package: Arrays related -Operating System: debian +Operating System: all
 [2020-03-22 15:37 UTC] vlad dot turchinskiy at yandex dot ru
Description:
------------
Referencing to SplFixedArray interrupts foreach loop.

Test script:
---------------
https://3v4l.org/FdN4i

Expected result:
----------------
3 iterations executed.

Actual result:
--------------
1 iteration executed.
 [2020-03-22 15:40 UTC] vlad dot turchinskiy at yandex dot ru
-Package: Arrays related +Package: SPL related
 [2020-03-22 15:40 UTC] vlad dot turchinskiy at yandex dot ru
Description:
------------
Referencing to SplFixedArray interrupts foreach loop.

Test script:
---------------
https://3v4l.org/FdN4i

Expected result:
----------------
3 iterations executed.

Actual result:
--------------
1 iteration executed.
 [2020-03-22 15:50 UTC] vlad dot turchinskiy at yandex dot ru
-PHP Version: 7.4.4 +PHP Version: 5.4.0 - 7.4.4
 [2020-03-22 15:50 UTC] vlad dot turchinskiy at yandex dot ru
Description:
------------
Referencing to SplFixedArray interrupts foreach loop.

Test script:
---------------
https://3v4l.org/FdN4i

Expected result:
----------------
3 iterations executed.

Actual result:
--------------
1 iteration executed.
 [2020-03-22 23:32 UTC] cmb@php.net
Presuming for Iterators

    foreach ($it as $el) {
        var_dump($el);
    }

is equivalent to

    for ($it->rewind(); $it->valid(); $it->next()) {
        $el = $it->current();
        var_dump($el);
    }

the behavior is correct.  On the other hand, SplDoublyLinkedList,
for instance, supports nested traversal via foreach ...
 [2020-03-23 01:51 UTC] vlad dot turchinskiy at yandex dot ru
cmb@php.net, as far as SPLFixedArray implements Traversable, it is expected to support foreach.

I updated code, to make the difference more obvious:
https://3v4l.org/N9k7P

Please, note, that in the test code i provided, unless we use $collection->getSum() inside the loop - it works as expected.
 [2020-03-23 11:03 UTC] cmb@php.net
Yes, a single foreach loop works certainly as expected; the
problem is *nesting* of foreach loops:

    <?php
    $spl = SplFixedArray::fromArray([0, 1]);
    foreach ($spl as $el1) {
        foreach ($spl as $el2) {
            echo "$el1.$el2\n";
        }
    }
    ?>

outputs

    0.0
    0.1

while you want to get

    0.0
    0.1
    1.0
    1.1

It seems to me that this behavior is correct for Iterators; maybe
not for IteratorAggregates.
 [2020-03-23 14:04 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2020-03-23 14:04 UTC] nikic@php.net
SplFixedArray should probably be IteratorAggregate rather than Iterator...

I do think we should ensure that multiple parallel get_iterator()s are supported independently of that.
 [2020-04-10 08:41 UTC] alexinbeijing at gmail dot com
> I do think we should ensure that multiple parallel get_iterator()s are supported independently of that.

Nikita, I don't understand how SplFixedArray could possibly support multiple parallel get_iterator()s while still following the contract of the Iterator interface. Could you explain what you mean?
 [2020-04-10 14:31 UTC] requinix@php.net
> Nikita, I don't understand how SplFixedArray could possibly support multiple
> parallel get_iterator()s while still following the contract of the Iterator
> interface. Could you explain what you mean?
To make sure that all the Traversables returned by multiple calls to getIterator() won't conflict with each other.
 [2020-04-14 08:19 UTC] alexinbeijing at gmail dot com
I have a patch which "fixes" get_iterator() without converting SplFixedArray to an IteratorAggregate. It's a pretty dubious idea. Still, I may push it to GH for review and comments.
 [2020-04-14 09:06 UTC] alexinbeijing at gmail dot com
The following pull request has been associated:

Patch Name: SplFixedArray can be used in nested 'foreach' loops
On GitHub:  https://github.com/php/php-src/pull/5384
Patch:      https://github.com/php/php-src/pull/5384.patch
 [2021-01-08 15:17 UTC] cmb@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: cmb
 [2021-01-08 15:17 UTC] cmb@php.net
The fix for this issue has been committed[1], and will be
available as of PHP 8.1.0 for BC reasons.

[1] <https://github.com/php/php-src/commit/4222ae16e7848e0b3f062a9a989d387de307a7af>
 [2021-01-08 15:28 UTC] nikic@php.net
(Correction: This is fixed in 8.0.0, rather than 8.1.0.)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 13:01:31 2024 UTC