Iterator

<?php

interface Iterator extends Traversable
{
    public function current(): mixed;
    public function key(): mixed;
    public function next(): void;
    public function rewind(): void;
    public function valid(): bool;
}

Вграден интерфейс, който може да направи цикленето с foreach по-гъвкаво и къстъмизирано. Демек, да може да се задават определени действия за всяка итерация, задължавайки итериращият клас да имплементира тези действия.

Демек, ако имаме например обект, който имплементира този интерфейс, и го изциклим с foreach, при всяка итерация, в определен ред, ще бъдат извикани гореспоменатите методи.

Нека разгледаме следният пример:

<?php

class MyIterator implements IteratorInterface
{
    private int $position = 0;

    private array $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );

    public function __construct()
    {
        $this->position = 0;
    }

    public function rewind(): void
    {
        var_dump(__METHOD__);
        $this->position = 0;
    }

    public function current(): mixed
    {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }

    public function key(): mixed
    {
        var_dump(__METHOD__);
        return $this->position;
    }

    public function next(): void
    {
        var_dump(__METHOD__);
        ++$this->position;
    }

    public function valid(): bool
    {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
    }
}

$it = new myIterator;

foreach ($it as $key => $value) {
    var_dump($key, $value);
    echo "\n\n";
}

Имаме обект, имплементиращ въпросният интерфейс, и го циклим.

string(18) "myIterator::rewind"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(0)
string(12) "firstelement"


string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(1)
string(13) "secondelement"


string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(2)
string(11) "lastelement"


string(16) "myIterator::next"
string(17) "myIterator::valid"

Вижда се ясно в какъв ред автоматично се викат отделните методи.

Просто казано, идеята е да можем по свой начин, чрез всеки метод да зададем какво да се случва при всяка итерация.

Литература:

https://www.php.net/manual/en/class.iterator.php