iterator_to_array

Copies the elements of an iterator or generator into a plain PHP array.

Signature
iterator_to_array(Traversable|array $iterator, bool $preserve_keys = true): array
  • Added in PHP 5.1.0

Parameters

ParameterTypeDescription
$iteratorTraversable|arrayThe iterator, generator or array being copied.
$preserve_keysoptionalbool= trueWhether to use the iterator's own keys as array keys. When false, the result is renumbered from 0.

Return value

arrayAn array containing the elements of the iterator.

Errors

Throws a TypeError if the argument is neither Traversable nor (as of PHP 8.2) an array. An infinite iterator will exhaust memory rather than throw.

Changelog

  • PHP 8.2.0The iterator parameter was widened from Traversable to Traversable|array, so plain arrays may now be passed.

iterator_to_array() drains a Traversable — a generator, an ArrayIterator, a DirectoryIterator, any class implementing Iterator or IteratorAggregate — into an array you can count, sort, slice or json_encode.

Since PHP 8.2 it also accepts a plain array, which makes it safe to call on an iterable parameter without first testing with is_array().

When to reach for it

  • You wrote a generator for laziness but one caller needs the whole result at once — to count() it, sort it, or return it as JSON.
  • Normalising an iterable API parameter so the rest of the function can use array functions.
  • Assertions in tests, where comparing arrays is far easier than comparing iterators.

What trips people up

$preserve_keys defaults to true, and generators are free to yield duplicate keys — every yield $value; without a key restarts at 0 in some nesting patterns, and yield from famously reuses the inner generator's keys. Duplicates silently overwrite, so you get fewer elements than you yielded. Pass false whenever you want every value and do not care about keys.

The other trap is unbounded input: calling this on an infinite generator or a huge stream buffers everything into memory. Combine with LimitIterator, or keep iterating lazily instead.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Turning a generator that reads and parses a file into an array for a JSON response.
  • Normalising an iterable function parameter so array_map and array_filter can be used on it.
  • Collecting the results of a yield from composition in a test so they can be compared with an expected array.

Frequently asked questions

Can I pass an array to iterator_to_array?

Yes, since PHP 8.2. Earlier versions throw a TypeError, so code supporting PHP 8.1 and below still needs an is_array() check first.

Why does iterator_to_array return fewer elements than my generator yielded?

Because preserve_keys is true by default and duplicate keys overwrite each other, which is common with yield from. Pass false as the second argument to keep every value.

Does iterator_to_array work on an infinite generator?

No — it will keep buffering until memory runs out. Wrap the iterator in a LimitIterator, or break out of a normal foreach instead.

More examples

Duplicate keys silently collapse

The first call returns only two elements because the second yield from reuses keys 0 and 1 and overwrites the earlier values. Passing false keeps all four, which is almost always what the code intended.

Example · php
<?php
function inner(): Generator { yield 1; yield 2; }
function outer(): Generator {
    yield from inner();   // keys 0 and 1
    yield from inner();   // keys 0 and 1 again
}

print_r(iterator_to_array(outer()));
print_r(iterator_to_array(outer(), false));
echo count(iterator_to_array(outer(), false)), "\n";

Normalising an iterable parameter

All three inputs work through the same code path because PHP 8.2 widened the parameter to Traversable|array. Before 8.2 the array case would have needed an is_array() branch.

Example · php
<?php
function total(iterable $values): int {
    return array_sum(iterator_to_array($values, false));
}

function gen(): Generator { yield 1; yield 2; yield 3; }

echo total([1, 2, 3]), "\n";     // plain array, PHP 8.2+
echo total(gen()), "\n";          // generator
echo total(new ArrayIterator([4, 5])), "\n";

Discussion

  • Be the first to comment on this lesson.