PHP Iterables
In this page:
What Counts as Iterable
Two kinds of values satisfy the iterable type: any plain PHP array, and any object that implements the built-in Traversable interface (which includes both the Iterator interface and Generator functions) -- both can be the target of a foreach loop.
Note: Think of iterable as "anything foreach can walk through", rather than trying to memorize every specific class that qualifies.
Warning: A plain object that does NOT implement Traversable, even if it holds a collection of data internally, does not satisfy the iterable type hint.
Example: What Counts as Iterable
<?php
function gen() {
yield 1;
yield 2;
}
var_dump(is_iterable([1, 2, 3]));
var_dump(is_iterable(gen()));
?>
Login to try C/C++/Java/PHP code in the editor
Using iterable as a Parameter Type
Type-hinting a function parameter as iterable instead of array signals that the function will only ever loop over the input with foreach, and does not require it to specifically be a real array -- making the function usable with a wider range of inputs, including large generators.
Note: Choose iterable over array for any function that genuinely only needs to loop through its input once and never needs array-specific operations like count() or array_map().
Warning: A function hinted as iterable cannot safely call array-only functions like count(), sort(), or array_push() on its parameter, since a Generator does not support them.
Example: Using iterable as a Parameter Type
<?php
function printAll(iterable $items) {
foreach ($items as $item) {
echo $item . "\n";
}
}
printAll([1, 2, 3]);
?>
Login to try C/C++/Java/PHP code in the editor
Using iterable as a Return Type
A function can also declare its return type as iterable, signaling that it will return something loopable -- either a real array it builds up, or a generator using yield -- without committing to which specific one, giving the function's implementation flexibility to change later.
Note: Returning a generator (yield) instead of a built array can save significant memory for large datasets, since values are produced one at a time instead of all being held in memory at once.
Warning: Code calling a function with an iterable return type should not assume the result supports array functions like count() -- treat it as foreach-only unless you know the concrete type.
Example: Using iterable as a Return Type
<?php
function numbers(): iterable {
yield 1;
yield 2;
yield 3;
}
foreach (numbers() as $n) {
echo $n . "\n";
}
?>
Login to try C/C++/Java/PHP code in the editor
The One-Time-Use Nature of Generators
Unlike an array, which can be looped over as many times as you like, a Generator can only be iterated once -- once a foreach loop over a generator finishes, looping over that same generator object again produces nothing at all, since its internal position has already advanced to the end.
Note: If a value received as iterable needs to be used more than once, convert it to a real array first with iterator_to_array(), which "materializes" a generator into a reusable array.
Warning: Looping an already-exhausted generator a second time does not raise an error -- it simply produces zero iterations, which can silently hide a bug.
Example: The One-Time-Use Nature of Generators
<?php
function gen() {
yield 1;
yield 2;
}
$g = gen();
foreach ($g as $v) { echo $v . "\n"; }
foreach ($g as $v) { echo "second pass: $v\n"; } // never runs
echo "done";
?>
Login to try C/C++/Java/PHP code in the editor
iterable vs array: Choosing the Right Type Hint
Use array specifically when a function genuinely needs array-only capabilities like count(), sorting, or random access by key. Use iterable when a function only ever needs to walk through the values once with foreach -- accepting a wider range of input types at no real cost.
Note: When designing a new function, default to the narrowest type hint that still does the job -- iterable if a simple foreach loop is all you need, array if you genuinely need array-specific behavior.
Warning: Widening an existing function's parameter from array to iterable is usually a safe change; narrowing from iterable to array can break any caller currently passing in a generator.
Example: iterable vs array: Choosing the Right Type Hint
<?php
function countItems(array $items) {
return count($items); // needs real array capabilities
}
function printItems(iterable $items) {
foreach ($items as $item) {
echo $item . "\n"; // only ever loops
}
}
echo countItems([1, 2, 3]);
?>
Login to try C/C++/Java/PHP code in the editor
- Assuming iterable means "array" specifically, and then calling array-only functions (like array_push()) on a parameter type-hinted as iterable, which fails if a Traversable object is passed instead.
- Forgetting that an iterable parameter might be a Generator, which can only be looped over once -- looping it a second time yields nothing.
- Type-hinting a parameter as array when iterable would be more flexible and just as safe for a function that only ever loops over its input with foreach.
- iterable is a pseudo-type (available since PHP 7.1) representing anything that can be looped over with foreach: an array, or any object implementing Traversable.
- A function parameter or return type hinted as iterable accepts both plain arrays and iterator/generator objects interchangeably.
- Because a Generator can only be iterated once, code that receives an iterable should not assume it can be looped over multiple times without checking.
The iterable type hint has been available since PHP 7.1 and works identically on every PHP 7.1+ environment.
Chapter Quiz — Complete all 24 topics to unlock
0/24 topics done
Complete these topics first:
- PHP Date & Time
- PHP Math Functions
- PHP JSON Handling
- PHP XML Handling
- PHP cURL Introduction
- PHP REST API Basics
- PHP Composer & Packages
- PHP Autoloading
- PHP Design Patterns
- PHP MVC Architecture
- PHP Security Best Practices
- PHP Performance Optimization
- PHP 8 New Features
- PHP Type Declarations
- PHP Match Expression Advanced
- PHP Fibers
- PHP Attributes
- PHP Magic Constants
- PHP Include & Require
- PHP Iterables
- PHP SimpleXML Parser
- PHP SimpleXML Get
- PHP XML Expat Parser
- PHP DOM Parser