====== PHP RFC: Make the iterator_*() family accept all iterables ======
* Version: 1.0
* Date: 2022-06-21
* Author: Tim Düsterhus, duesterhus@woltlab.com
* Status: Implemented
* Target Version: PHP 8.2
* Implementation: https://github.com/php/php-src/commit/7ae7df5b4601f3f0ce45a27324fb9c6ebcbfc9ed
* First Published at: http://wiki.php.net/rfc/iterator_xyz_accept_array
===== 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.
* Yes
* No
* Yes
* No
===== Patches and Tests =====
https://github.com/php/php-src/pull/8819
===== Implementation =====
https://github.com/php/php-src/commit/7ae7df5b4601f3f0ce45a27324fb9c6ebcbfc9ed
===== References =====
* Pre-RFC discussion: https://externals.io/message/117979
* PoC implementation: https://github.com/php/php-src/pull/8819
* Similar previous RFC that proposed adding **new** functions with an iterable_* prefix: https://wiki.php.net/rfc/iterable_to_array-and-iterable_count
* Stack Overflow asking for iterable_to_array(): https://stackoverflow.com/q/44587973/782822
===== Rejected Features =====
none