Table of Contents

PHP RFC: Make the iterator_*() family accept all iterables

Introduction

PHP's iterator_*() family currently only accept \Traversables (i.e. they reject plain arrays). This is unnecessarily limiting.

Specifically this concerns the iterator_to_array() and iterator_count() functions. While each of them has an array-specific counterpart, the fact that one needs to choose either the array-specific variant or the everything-but-array variant makes writing code the deals with arbitrary iterables unnecessarily verbose.

As an example: Allowing iterator_to_array() to take an array, makes it much easier to write functions accepting an iterable and processing it using array_map() et al:

function before(iterable $foo) {
    if (!is_array($foo)) {
        $foo = iterator_to_array($foo);
    }
 
    return array_map(strlen(...), $foo);
}
function after(iterable $foo) {
    $foo = iterator_to_array($foo);
 
    return array_map(strlen(...), $foo);
}

Proposal

The $iterator parameter of iterator_to_array() and iterator_count() should be widened from \Traversable to iterable (i.e. to \Traversable|array).

Specifically if this RFC is accepted the following shall hold:

iterator_to_array

iterator_to_array($array, true) == $array
iterator_to_array($array, false) == array_values($array)

iterator_count

iterator_count($array) == count($array)

iterator_apply

This function is not part of this proposal, because it is non-obvious how to define the behavior for arrays, given that it does not pass the Iterator to the callback by default.

Backward Incompatible Changes

None, this is a purely type widening change.

Proposed PHP Version(s)

next PHP 8.x

RFC Impact

To SAPIs

none

To Existing Extensions

none

To Opcache

none

New Constants

none

php.ini Defaults

none

Open Issues

none

Unaffected PHP Functionality

Anything that isn't iterator_to_array() or iterator_count().

Future Scope

none

Proposed Voting Choices

Each vote requires a 2/3 majority.

Voting opened 2022-07-05 14:30 UTC and closes on 2022-07-19 14:45 UTC.

iterator_to_array: Change the type of iterator_to_array()’s $iterator parameter from \Traversable to iterable?
Real name Yes No
asgrim (asgrim)  
bwoebi (bwoebi)  
colinodell (colinodell)  
crell (crell)  
jwage (jwage)  
kalle (kalle)  
kguest (kguest)  
levim (levim)  
marandall (marandall)  
nicolasgrekas (nicolasgrekas)  
ocramius (ocramius)  
reywob (reywob)  
salathe (salathe)  
santiagolizardo (santiagolizardo)  
sergey (sergey)  
svpernova09 (svpernova09)  
timwolla (timwolla)  
trowski (trowski)  
weierophinney (weierophinney)  
Final result: 17 2
This poll has been closed.
iterator_count: Change the type of iterator_count()’s $iterator parameter from \Traversable to iterable?
Real name Yes No
asgrim (asgrim)  
bmajdak (bmajdak)  
bwoebi (bwoebi)  
colinodell (colinodell)  
crell (crell)  
jwage (jwage)  
kalle (kalle)  
kguest (kguest)  
levim (levim)  
nicolasgrekas (nicolasgrekas)  
ocramius (ocramius)  
reywob (reywob)  
salathe (salathe)  
santiagolizardo (santiagolizardo)  
sergey (sergey)  
svpernova09 (svpernova09)  
timwolla (timwolla)  
trowski (trowski)  
weierophinney (weierophinney)  
Final result: 17 2
This poll has been closed.

Patches and Tests

https://github.com/php/php-src/pull/8819

Implementation

https://github.com/php/php-src/commit/7ae7df5b4601f3f0ce45a27324fb9c6ebcbfc9ed

References

Rejected Features

none