PHP Iterables
In this page:
function function_name(iterable $items): iterable {
foreach ($items as $item) {
yield $item;
}
}
is_iterable($value);
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.
Example: What Counts as Iterable
<?php
// Define the function `gen` with no parameters
function gen() {
yield 1;
yield 2;
}
// Print a detailed dump (with types) of `is_iterable([1, 2, 3])`
var_dump(is_iterable([1, 2, 3]));
// Print a detailed dump (with types) of `is_iterable(gen())`
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.
Example: Using iterable as a Parameter Type
<?php
// Define the function `printAll` taking `iterable $items`
function printAll(iterable $items) {
// Loop over `$items`, binding each item to `$item`
foreach ($items as $item) {
// Print `$item . "\n"` to the output
echo $item . "\n";
}
}
// Call `printAll([1, 2, 3])`
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.
Example: Using iterable as a Return Type
<?php
// Define the function `numbers` with no parameters
function numbers(): iterable {
yield 1;
yield 2;
yield 3;
}
// Loop over `numbers()`, binding each item to `$n`
foreach (numbers() as $n) {
// Print `$n . "\n"` to the output
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.
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.
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