PHP – Причины использования итераторов?

Сегодня я изучал руководство и замечал различные итераторы . Мне кажется, что все они несколько бессмысленны; Я не вижу причины использовать их, если вы предпочитаете их синтаксис, или не знаете, как написать рекурсивную функцию. Существуют ли какие-либо причины использовать встроенные итераторы в PHP, просто написав цикл или сделав рекурсивный метод?

Я ищу только фактические ответы, а не субъективные предпочтения (т. Е. Меня не волнует, если вы считаете, что это более «читаемый» или «более объектно-ориентированный», я хочу знать, быстрее ли они, предлагают функциональность, которая может не достигаются, когда вы переворачиваете свои собственные и т. д.).

Я считаю, что главная причина – универсальность. Они не делают вещи более читаемыми, и вы можете выполнить большую часть того, что делают итераторы spl с простым foreach .

Но итераторы могут служить своего рода уплотненным контуром или источником петли, который вы можете пройти. У вас могут быть более разнообразные источники данных, чем просто список / массив. И реальным преимуществом является то, что вы можете обертывать или складывать их для агрегации.

Именование несколько неочевидно, но я думаю, вы могли бы использовать AppendIterator чтобы, например, объединить статический список имен файлов и результат DirectoryIterator . Или иначе оберните это в LimitIterator вместо hardwiring, что в условие. Все это довольно простые функции, и их можно выполнять вручную в режиме foreach. Но, по крайней мере, RegexIterator и FilterIterator кажутся подходящими для уменьшения сложности.

Но, в конце концов, это действительно стилистический выбор. Это имеет смысл, если у вас есть пользовательские объекты, которые пересекают что-либо (например, объект VFS, который может указывать на реальные файлы или записи в базе данных). Но даже тогда вы могли бы просто iterator_to_array преобразовать такой список и использовать обычный foreach -over-array.

Единственным случаем было очень важно предпочесть, чтобы итераторы были, если источник данных не ограничен по размеру. Раскрытые массивы для использования в foreach могут потреблять больше памяти, чем итератор, который может извлекать элемент за элементом.

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

  • Лень
  • Сокращение использования памяти
  • Состав

Лень

С поставщиками данных данные извлекаются только тогда, когда вам это действительно нужно (например, когда вы итерации).

Сокращение использования памяти

Итераторы рекомендуют обрабатывать данные итеративно, а не буферизировать их в памяти. Хотя это можно сделать без итераторов, абстракции, которые они предоставляют, скрывают реализацию, которая делает их очень простыми в использовании.

Состав

Что сказал Марио.


Juozas Kaziukėnas недавно написал сообщение в блоге о том, как он мог использовать итераторы, чтобы подражать ленивой оценке в PHP. Он подробно рассказывает о некоторых вещах, о которых я упоминал.

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

Для этого вы можете implement интерфейс Iterator который определяет методы public current() , public key() , public next() , public rewind() и public valid() .

Или вы можете просто implement альтернативный интерфейс IteratorAggregate который определяет один метод public getIterator() который просто возвращает Iterator для внутренних данных, которые вы хотите открыть.

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

Вопрос может иметь очень широкий спектр ответов, но правильные ответы, вероятно, можно обобщить как: Iterator можно использовать для итерации чего-либо более сложного, чем простой массив .

Одним из примеров является какой-то ORM или построитель запросов. Предположим, что у нас есть одно – использование этого может выглядеть так:

 $friends = new Model_Friend(); $friends = $people->where('age','>',30)->where('gender','=','female'); foreach ($friends as $friend) { echo $friend->name; } 

Итераторы так же быстро, как и все остальное, но с более легким интерфейсом и, возможно, большим количеством слов, чтобы обернуть его. Однако главное преимущество заключается не в том, что вам может понадобиться прямо сейчас, а в том, как вы можете расширить их для решения ваших будущих проблем ( и они придут!), и это то, что мы, старые мальчики, называем «спасая вашу будущую задницу». 🙂