Как работает класс PHP IteratorIterator?

Как бы я ни старался, я не могу понять, что на самом деле делает класс IteratorIterator. Я понимаю, что классы могут реализовывать Traversable, поэтому движок знает, что он может зацикливаться, используя foreach и я понимаю, что IteratorIterator должен преобразовывать все, что является Traversable, в Iterator, но я не могу понять, как это сделать.

Возьмем, к примеру, класс PDOStatement; как будут реализованы стандартные методы итератора (следующий, ключ, перемотка и т. д.), чтобы разрешить итерацию по PDOStatement?

Извините, если мой вопрос неясен, я просто пытаюсь понять точную причину этого класса, а документации по нему мало.

Спасибо,

Воля

Обновление: просматривая файлы phpt, я нашел один тест, который использует IteratorIterator:

<?php

$root = simplexml_load_string('<?xml version="1.0"?>
<root>
    <child>Hello</child>
    <child>World</child>
</root>
');

foreach (new IteratorIterator($root->child) as $child) {
    echo $child."\n";
}

?>

Ожидаемый результат:

Hello
World

Я действительно не понимаю, как конструкция IteratorIterator принимает $root->child в качестве аргумента и как ей удается перебирать дочерние элементы.


person WilliamMartin    schedule 02.09.2009    source источник
comment
Я нашел ответ здесь. Но мне кажется, что IteratorIterator становится теперь маловажным, не так ли?   -  person akond    schedule 13.01.2012


Ответы (3)


Основываясь на этом, я думаю, что это позволяет вам выполнять итерацию по итерируемым объектам. . т.е. вы можете вытащить другие объекты в своем главном объекте и, используя IteratorIterator на своем главном объекте, также выполнить итерацию дочерних объектов.

ОБНОВЛЕНИЕ: на основе вашего обновления. Для меня это имеет смысл, хотя есть только один корневой объект, поэтому его итерация на самом деле не применима в этом примере, но вы могли бы, если бы корневых объектов было больше. Другими словами, я считаю, что IteratorIterator — это то же самое, что вложенные циклы foreach, без необходимости знать все элементы каждого объекта. Другими словами, вложенный foreach с использованием объектно-ориентированных объектов... есть лишний оператор. :-)

person Scott Lundberg    schedule 02.09.2009

Если вы еще не нашли его, https://www.phpro.org/tutorials/Introduction-to-SPL.html содержит несколько примеров, которые могут вам помочь.


ИтераторИтератор >

  • «Эта оболочка итератора позволяет преобразовывать все, что является Traversable, в итератор».

Проходной >

  • «Интерфейс для определения возможности обхода класса с помощью foreach».
  • «Внутренние (встроенные) классы, реализующие этот интерфейс, могут использоваться в конструкции foreach, и им не нужно реализовывать IteratorAggregate или Iterator».
  • «Это внутренний интерфейс движка, который нельзя реализовать в PHP-скриптах. Вместо этого следует использовать либо IteratorAggregate, либо Iterator».

На сайте есть несколько примеров RecursiveIteratorIterator, которые могут оказаться полезными, но, если я правильно понял, IteratorIterator с точки зрения сценариев довольно бесполезен (по крайней мере, когда он используется для foreach).

Он создает итерируемые объекты из объектов, реализующих интерфейс Traversable, но внутренние классы, реализующие интерфейс Traversable, в любом случае доступны для доступа, а скрипты не могут реализовать Traversable...

(Не упоминается в документах, SimpleXMLElement реализует Traversable)

person Kuchen    schedule 06.06.2010

я думал, что пример № 2 здесь довольно прост...
он в основном позволяет реализовать конкретное поведение вашего класса для следующих/предыдущих/текущих/перемоток/клавишных функций массива, ожидаемое синтаксическим анализатором php foreach.

поэтому для реализации вашего вопроса можно было бы создать класс Iterator с PDOStatement в качестве его члена, а затем, например, использовать следующий метод для вызова PDOStatement::fetch, чтобы вернуть его следующий оператор. его хранение позволит вам реализовать как perivous, так и current. не использовал этот класс слишком много, но я уверен, что это не так сложно реализовать перемотку и ключ. обратите внимание, что это на лету, поэтому я могу ошибаться в деталях, но я думаю, что концепция должна быть ясной

person AriehGlazer    schedule 02.09.2009
comment
Я не уверен, что следую. Пример, на который вы ссылаетесь, говорит о стандартном Iterator, а не о классе IteratorIterator (us2.php .net/manual/en/class.iteratoriterator.php). Не могли бы вы уточнить? - person WilliamMartin; 02.09.2009