Question
How can I make my PHP class iterable so I can use foreach syntax?
<?php
class MyCollection implements Iterator {
private $items = [];
private $currentIndex = 0;
public function __construct($items) {
$this->items = $items;
}
public function current() {
return $this->items[$this->currentIndex];
}
public function key() {
return $this->currentIndex;
}
public function next() {
++$this->currentIndex;
}
public function rewind() {
$this->currentIndex = 0;
}
public function valid() {
return isset($this->items[$this->currentIndex]);
}
}
$collection = new MyCollection(['item1', 'item2', 'item3']);
foreach ($collection as $key => $value) {
echo "$key: $value\n";
}
?>
Answer
To use foreach syntax with a class in PHP, you need to make it iterable by implementing the Iterator interface. This interface requires defining several methods that control the access to your collection of data. Here’s how you can do it step-by-step.
<?php
class MyCollection implements Iterator {
private $items = [];
private $currentIndex = 0;
public function __construct($items) {
$this->items = $items;
}
public function current() {
return $this->items[$this->currentIndex];
}
public function key() {
return $this->currentIndex;
}
public function next() {
++$this->currentIndex;
}
public function rewind() {
$this->currentIndex = 0;
}
public function valid() {
return isset($this->items[$this->currentIndex]);
}
}
$collection = new MyCollection(['item1', 'item2', 'item3']);
foreach ($collection as $key => $value) {
echo "$key: $value\n";
}
?>
Causes
- The class does not implement the Iterator interface.
- Methods required by the Iterator interface are not defined.
Solutions
- Implement the Iterator interface and define the required methods: current(), key(), next(), rewind(), and valid().
- Ensure the class manages its state properly, such as maintaining the current index.
Common Mistakes
Mistake: Failing to implement all required methods of the Iterator interface.
Solution: Ensure you have defined current(), key(), next(), rewind(), and valid() methods in your class.
Mistake: Not managing the internal state of the index properly.
Solution: Always reset the index in rewind() and return the correct boolean for valid().
Helpers
- make class iterable PHP
- PHP foreach custom class
- use foreach with class PHP