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

- Status: Implemented (PHP 8.2)
- Authors: Tim Düsterhus, duesterhus@woltlab.com
- Date: 2022-06-21
- Version: 1.0
- Target: PHP 8.2
- Implementation: https://github.com/php/php-src/commit/7ae7df5b4601f3f0ce45a27324fb9c6ebcbfc9ed
- Original: https://wiki.php.net/rfc/iterator_xyz_accept_array
- Page: https://externals.io/rfc/iterator_xyz_accept_array
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### iterator_to_array: Change the type of iterator_to_array()’s $iterator parameter from \Traversable to iterable? (closed)

Yes: 17 · No: 2

Voters: asgrim (Yes), bwoebi (Yes), colinodell (Yes), crell (Yes), jwage (Yes), kalle (Yes), kguest (Yes), levim (No), marandall (Yes), nicolasgrekas (Yes), ocramius (Yes), reywob (Yes), salathe (No), santiagolizardo (Yes), sergey (Yes), svpernova09 (Yes), timwolla (Yes), trowski (Yes), weierophinney (Yes)

### iterator_count: Change the type of iterator_count()’s $iterator parameter from \Traversable to iterable? (closed)

Yes: 17 · No: 2

Voters: asgrim (Yes), bmajdak (Yes), bwoebi (Yes), colinodell (Yes), crell (Yes), jwage (Yes), kalle (Yes), kguest (Yes), levim (No), nicolasgrekas (Yes), ocramius (Yes), reywob (Yes), salathe (No), santiagolizardo (Yes), sergey (Yes), svpernova09 (Yes), timwolla (Yes), trowski (Yes), weierophinney (Yes)

## Discussions on the mailing list

- [Make iterator_to_array() accept all iterables](https://externals.io/message/117979.md) — started on 2022-06-17, 7 messages
- [\[RFC\] Make the iterator_*() family accept all iterables](https://externals.io/message/118036.md) — started on 2022-06-21, 4 messages
- [\[VOTE\] \[RFC\] Make the iterator_*() family accept all iterables](https://externals.io/message/118199.md) — started on 2022-07-05, 2 messages
- [Proposal: Expanded iterable helper functions and aliasing iterator_to_array in `iterable\` namespace](https://externals.io/message/118896.md) — started on 2022-10-28, 7 messages

---

## Introduction

PHP's `iterator_*()` family currently only accept `\Traversable`s (i.e. they reject plain `array`s). 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 `iterable`s 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:

```php
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

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

### iterator\_count

```php
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 `array`s, 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.

**Vote: iterator\_to\_array: Change the type of iterator\_to\_array()’s $iterator parameter from \\Traversable to iterable?** — Yes: 17 · No: 2 (closed)

**Vote: iterator\_count: Change the type of iterator\_count()’s $iterator parameter from \\Traversable to iterable?** — Yes: 17 · No: 2 (closed)

## 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://externals.io/rfc/iterable\_to\_array-and-iterable\_count](https://externals.io/rfc/iterable_to_array-and-iterable_count)
- Stack Overflow asking for `iterable_to_array()`: <https://stackoverflow.com/q/44587973/782822>

## Rejected Features

none
