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

Колкото и да се опитвам, не мога да разбера какво всъщност прави класът IteratorIterator. Разбирам, че класовете могат да имплементират Traversable, така че двигателят да знае, че може да прави цикъл с помощта на foreach и осъзнавам, че IteratorIterator трябва да преобразува всичко, което е Traversable, в Iterator, но не мога да разбера как.

Вземете например класа PDOStatement; как ще бъдат внедрени стандартните методи на Iterator (следващ, ключ, пренавиване и т.н.), за да се позволи итерация върху 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 има няколко примера, които могат да ви помогнат.


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

  • „Тази обвивка на итератор позволява преобразуването на всичко, което е обходимо, в итератор.“

Проходима >

  • „Интерфейс за откриване дали даден клас е проходим с помощта на foreach.“
  • „Вътрешните (вградени) класове, които имплементират този интерфейс, могат да се използват в конструкция foreach и не е необходимо да имплементират IteratorAggregate или Iterator.“
  • „Това е вътрешен интерфейс на двигателя, който не може да бъде внедрен в PHP скриптове. Вместо това трябва да се използва IteratorAggregate или Iterator.“

Сайтът има някои примери за RecursiveIteratorIterator, които може да са полезни, но ако съм разбрал правилно, IteratorIterator е доста безполезен от гледна точка на скриптове (когато се използва поне за foreach).

Той създава Iterateable Objects от Objects, имплементиращи 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