====== 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