PHP Iterables
Working with arrays and traversable objects
🔄 What are PHP Iterables?
An iterable is any value that can be looped through with a foreach loop. This includes arrays and objects that implement the Traversable interface, providing a flexible way to work with collections.
<?php
// Simple iterable example
function printItems(iterable $items) {
foreach ($items as $item) {
echo $item . " ";
}
}
printItems([1, 2, 3]); // 1 2 3
?>
Why Use Iterables?
Flexibility
Accept arrays or objects in functions
Type Safety
Ensure parameters can be looped
Collections
Work with any collection type
Clean Code
Write more generic functions
🔹 Basic Iterable Type Hint
The iterable type hint was introduced in PHP 7.1 and accepts both arrays and objects implementing the Traversable interface, making functions more flexible.
<?php
function displayList(iterable $items) {
$output = "";
foreach ($items as $item) {
$output .= $item . "<br>";
}
return $output;
}
// Works with arrays
$fruits = ["Apple", "Banana", "Orange"];
echo displayList($fruits);
// Also works with iterators
$numbers = new ArrayIterator([1, 2, 3]);
echo displayList($numbers);
?>
Output:
Apple
Banana
Orange
1
2
3
🔹 Iterable Return Type
Functions can declare iterable as a return type, guaranteeing they will return something that can be looped through with foreach.
<?php
function getNumbers(): iterable {
return [1, 2, 3, 4, 5];
}
function getColors(): iterable {
yield "Red";
yield "Green";
yield "Blue";
}
// Use returned iterables
foreach (getNumbers() as $num) {
echo $num . " ";
}
echo "<br>";
foreach (getColors() as $color) {
echo $color . " ";
}
?>
Output:
1 2 3 4 5
Red Green Blue
🔹 Arrays as Iterables
Arrays are the most common type of iterable in PHP. They can be easily passed to functions expecting iterable parameters and looped through efficiently.
<?php
function sumValues(iterable $numbers): int {
$total = 0;
foreach ($numbers as $number) {
$total += $number;
}
return $total;
}
function multiplyValues(iterable $numbers, int $multiplier): array {
$result = [];
foreach ($numbers as $number) {
$result[] = $number * $multiplier;
}
return $result;
}
$values = [10, 20, 30];
echo "Sum: " . sumValues($values) . "<br>";
echo "Multiplied: " . implode(", ", multiplyValues($values, 2));
?>
Output:
Sum: 60
Multiplied: 20, 40, 60
🔹 Generators as Iterables
Generators are functions that use yield to produce values one at a time. They implement the Iterator interface automatically, making them perfect iterables for memory-efficient loops.
<?php
function countTo(int $max): iterable {
for ($i = 1; $i <= $max; $i++) {
yield $i;
}
}
function evenNumbers(int $max): iterable {
for ($i = 2; $i <= $max; $i += 2) {
yield $i;
}
}
echo "Count to 5: ";
foreach (countTo(5) as $num) {
echo $num . " ";
}
echo "<br>Even numbers to 10: ";
foreach (evenNumbers(10) as $num) {
echo $num . " ";
}
?>
Output:
Count to 5: 1 2 3 4 5
Even numbers to 10: 2 4 6 8 10
🔹 Iterator Objects
PHP provides built-in iterator classes like ArrayIterator that implement the Traversable interface, allowing you to iterate over data with additional functionality.
<?php
function processIterable(iterable $data): string {
$result = "";
$count = 0;
foreach ($data as $key => $value) {
$count++;
$result .= "[$key] => $value<br>";
}
return "Items: $count<br>" . $result;
}
$array = ["name" => "John", "age" => 30];
$iterator = new ArrayIterator($array);
echo processIterable($iterator);
?>
Output:
Items: 2
[name] => John
[age] => 30
🔹 Custom Iterable Class
You can create custom classes that implement the Iterator interface, making them iterable and allowing them to be used in foreach loops with custom behavior.
<?php
class NumberRange implements Iterator {
private $start;
private $end;
private $current;
public function __construct($start, $end) {
$this->start = $start;
$this->end = $end;
$this->current = $start;
}
public function current() {
return $this->current;
}
public function key() {
return $this->current;
}
public function next() {
$this->current++;
}
public function rewind() {
$this->current = $this->start;
}
public function valid() {
return $this->current <= $this->end;
}
}
function showRange(iterable $range) {
$output = "";
foreach ($range as $num) {
$output .= $num . " ";
}
return $output;
}
$range = new NumberRange(1, 5);
echo showRange($range);
?>
Output:
1 2 3 4 5
🔹 Iterable with Keys and Values
Iterables preserve both keys and values, allowing you to access associative array keys or custom keys from iterator objects during iteration.
<?php
function displayKeyValue(iterable $data): string {
$output = "";
foreach ($data as $key => $value) {
$output .= "$key: $value<br>";
}
return $output;
}
// Associative array
$person = [
"name" => "Alice",
"email" => "[email protected]",
"role" => "Developer"
];
echo displayKeyValue($person);
?>
Output:
🔹 Practical Example: Data Processing
Iterables are perfect for data processing functions that need to work with various data sources, from simple arrays to complex database result sets.
<?php
class DataProcessor {
public static function filter(iterable $items, callable $callback): array {
$result = [];
foreach ($items as $item) {
if ($callback($item)) {
$result[] = $item;
}
}
return $result;
}
public static function map(iterable $items, callable $callback): array {
$result = [];
foreach ($items as $item) {
$result[] = $callback($item);
}
return $result;
}
}
$numbers = [1, 2, 3, 4, 5, 6];
// Filter even numbers
$even = DataProcessor::filter($numbers, fn($n) => $n % 2 == 0);
echo "Even: " . implode(", ", $even) . "<br>";
// Double all numbers
$doubled = DataProcessor::map($numbers, fn($n) => $n * 2);
echo "Doubled: " . implode(", ", $doubled);
?>
Output:
Even: 2, 4, 6
Doubled: 2, 4, 6, 8, 10, 12
🔹 Converting Iterables to Arrays
Sometimes you need to convert an iterable to an array for operations that require array-specific functions. Use iterator_to_array() for this purpose.
<?php
function generateSquares(int $max): iterable {
for ($i = 1; $i <= $max; $i++) {
yield $i * $i;
}
}
// Convert generator to array
$squares = iterator_to_array(generateSquares(5));
echo "Squares array: " . implode(", ", $squares) . "<br>";
echo "Count: " . count($squares) . "<br>";
echo "Sum: " . array_sum($squares);
?>
Output:
Squares array: 1, 4, 9, 16, 25
Count: 5
Sum: 55
🔹 When to Use Iterables
✅ Use Iterables When:
- Writing functions that loop through data
- You want to accept both arrays and objects
- Building generic collection processors
- Working with generators for memory efficiency
- Creating flexible APIs and libraries
- Processing database results or file streams
💡 Benefits:
- More flexible than array type hints
- Works with generators for lazy evaluation
- Supports custom iterator implementations
- Better type safety than mixed or no type hint
- Enables memory-efficient data processing
💡 Key Points to Remember:
- Iterables accept arrays and Traversable objects
-
Use
iterabletype hint for parameters and return types - Generators automatically implement Iterator
- All iterables can be used in foreach loops
- Iterables preserve keys and values
-
Convert iterables to arrays with
iterator_to_array() - More flexible than array type hints
- Introduced in PHP 7.1