Как работает класс PHP IteratorIterator?
Вопрос
Как бы я ни старался, я не могу понять, что на самом деле делает класс IteratorIterator.Я понимаю, что классы могут реализовывать Traversable, чтобы движок знал, что он может зацикливаться, используя foreach. и Я понимаю, что IteratorIterator должен преобразовывать все, что можно пройти, в 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 в качестве аргумента и как ей удается перебирать дочерние элементы.
Решение
На основе этот, Я думаю, это позволяет вам перебирать итерированные объекты.Т.е.вы можете извлекать другие объекты в свой главный объект и использовать IteratorIterator для своего главного объекта, а также выполнять итерацию дочерних объектов.
ОБНОВЛЯТЬ:Судя по вашему обновлению.Для меня это имеет смысл, хотя существует только один корневой объект, поэтому его итерация в данном примере не применима, но вы могли бы это сделать, если бы корневых объектов было больше.Другими словами, я считаю, что IteratorIterator — это то же самое, что вложенные циклы foreach, без необходимости знать все элементы каждого объекта.Другими словами, вложенный foreach с использованием объектно-ориентированных объектов...это лишнее утверждение.:-)
Другие советы
Если вы еще не нашли его, https://www.phpro.org/tutorials/Introduction-to-SPL.html есть несколько примеров, которые могут вам помочь.
ИтераторИтератор >
- «Эта итераторная обертка позволяет преобразовать все, что можно пройти в итератор».
Проходимый >
- «Интерфейс, чтобы обнаружить, если класс можно пройти с помощью Foreach».
- «Внутренние (встроенные) классы, которые реализуют этот интерфейс, могут использоваться в конструкции Foreach и не нуждаются в реализации итераторного или итератора».
- «Это внутренний интерфейс двигателя, который не может быть реализован в сценариях PHP.Вместо этого должен использоваться либо итератор, либо итератор ».
На сайте есть несколько примеров RecursiveIteratorIterator, которые могут быть полезны, но если я правильно понял, IteratorIterator с точки зрения сценариев довольно бесполезен (по крайней мере, когда он используется для foreach).
Он создает итерируемые объекты из объектов, реализующих интерфейс Traversable, но внутренние классы, реализующие интерфейс Traversable, в любом случае доступны для доступа, а сценарии не могут реализовать Traversable...
(В документации не упоминается, SimpleXMLElement реализует Traversable)
я думал пример №2 здесь вполне прямолинейно...
по сути, он позволяет вам реализовать определенное поведение для вашего класса для функций массива next/previous/current/rewind/key, ожидаемых парсером php foreach.
поэтому для реализации вашего вопроса можно создать класс Iterator с PDOStatement в качестве его члена, а затем, например, использовать следующий метод для вызова PDOStatement::fetch для возврата следующего оператора.его хранение позволит вам реализовать как прошлые, так и текущие.Я не слишком часто использовал этот класс, но держу пари, что реализовать перемотку и ключ не так уж и сложно.обратите внимание, что это на лету, поэтому я могу ошибаться в деталях, но я думаю, что концепция должна быть ясна