Как стать автором
Обновить

Комментарии 21

Ну как же нет…
Вот же: «В SPL включено несколько встроенных классов итераторов» и далее по тексту — ровно эта ссылка.

Впрочем, вы правы, список важный, продублировал в списке литературы.

И опять же вы говорите «важнее». «Список классов из SPL знать наизусть» важнее чем что? Чем знать о существовании iterable и о том, что это такое? Позвольте не согласиться.
Да, надо знать наизусть, если хочешь получить сертификат ZCE. Да, надо знать, что это и как этим пользоваться, если хочешь пройти собеседование с HR в том же Badoo и добраться до собеседования с технарями (из личного печального опыта, в поддержку #меняневзяли).
Соглашусь, что это лишнее и пользы на первых порах — ноль. Но если уж взялся, то доведи дел до конца. А то какие-то полумеры получаются. Тем более что задачу из темы статьи в итоге статья не решает. Только как ликбез для начинающих.
Спасибо за отзыв. Учту в будущих статьях.
Вам скучно жить без того, чтобы почитать что-нибудь умное?

Вот скажите, чем вас не устраивает функция pluck() [вот черт, ее же в php нету!], функция array_combine [вот черт, она же в пхп тупее утюга] и обычный олдскульный foreach?

На кой черт вам делать итерацию внутри обьекта и перебирать все его свойства?
Что вам мешает запросить список свойств в виде массива строк, а потом пройтись по ним через foreach?

Вы просто хотите стать умнее, или что? Какая польза в осознании итераторов? Ну кроме вашей возможности показать тимлиду как вы ловко перебираете данными в обьекте, и что вы, значит, понимаете, что объект это не то же самое что массив?

90% задач — собрать данные, объединить по массиву ключей, осуществить поиск, сохранить в базу.
Вы жить не можете без того, чтобы собрать это на итераторах?
На кой черт вам делать итерацию внутри обьекта и перебирать все его свойства?

PHP очень гибкий язык. Собственно, об этом и написана статья.

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

Разделять интерфейс и реализацию, понимаете? Не этому ли учат на первых лекциях по ООП?

90% задач — собрать данные, объединить по массиву ключей, осуществить поиск, сохранить в базу.

И тут нас настигают две проблемы.
1. Массив — не объект, у него нет специализированного типа, значит нет контроля типа, приходится городить сложную валидацию вместо простого instanceof
2. Массив — не объект, у него нет методов, поэтому приходится городить «внешние методы» и тут см. п. 1.
И мы с вами очень плавно переходим к тому, что нам нужны всё-таки типы и методы… А это что? Это классы и объекты. Чёрт… Засада какая!

Вы просто хотите стать умнее, или что?

Куда уж больше-то :)

Вот пример из практики.


Есть старый код. Функция возвращает массив, в который вычитываются строки из базы данных. Этот массив обрабатывается в куче мест по коду.


База разрослась и массив такой огромный, что уже неприлично. Надо вычитывать данные кусками. Переписывать все 20 мест, где происходит итерация по массиву? Да ну, неохота, да и рискованно слишком (это легаси никто не покрывал тестами). Куда практичнее реализовать в этой самой функции возврат итератора — код меняется только в одном месте, все легко протестировать.

Стоит тогда еще и ArrayAccess реализовать, т.к. в старом коде может оказаться конструккия вида
if(isset($users[500]) && $users[500]['name'] == 'Uasyaa') {
    $users[500]['role']  = 'Admin';
} 
Какая польза в осознании итераторов?

Например у нас есть проект, и мы получаем 500-ку. Смотрим в код ви видим.


foreach ($this->getAllUsers() as $user) {
   // много всякого
}

Пользователей у нас например пара сотен тысяч и оно просто валится по памяти.


Вопрос, как можно быстро сделать выборку данных чанками с использованием курсора с минимальным количеством изменений (а это только изменения в методе getAllUsers). Итераторы/генераторы применять нельзя, ибо зачем их осознавать.


Ну и всякие там "бесконечные" загрузки, стрим парсера… итераторы позволяют нам "инкапсулировать" сложности работы с данными под красивый и удобный интерфейс. Что бы клиентский код (то есть код который юзает наш код) не заморачивался с тем, вернули мы ему просто массивчик захардкоженный, или мы там под копотом поиск в ширину делаем на файловой системе.


p.s. только сейчас заметил что уже запостили похожий случай.

Действительно. Зачем же нужны эти ваши итераторы… https://toster.ru/q/392018
Ой с Вами даже общаться неинтересно, все такие разбирающиеся и понимающие, все такие умные что не передать. Язык с порогом входа в 1 день превратили в язык с порогом входа 10 лет и изучением типов итераторов, минусите, усложняйте, долбайтесь, Ваша жизнь не наша.

Откуда у тебя массив в 100 тысяч юзеров и на кой черт тебе массив в 200 тысяч? Ты слышал про SQL запросы, которые сделают за тебя выборку за доли секунды? другой раз кажется что нет.

И когда у тебя 200 тысяч айдишников уже отфильтрованных запросом. то обновить по ID — фигня вопрос. А вот выбирать из массива пхп из сотни тысяч записей десяток или сотню и делать это на PHP — да тут полюбому все ляжет, потому что гаечный ключ ремонтирует кран, а молотком забивают гвозди. Не наоборот.

Но ваш мультикультурализм умиляет. Если кто-то не согласен — надо его заминусить. Долбайтесь, ваш мирок узок.
Если кто-то не согласен — надо его заминусить.

Из ваших комментов непонятно — с чем именно вы несогласны?

С существованием в PHP типа iterable? Так не вопрос, предложите RFC на его удаление из языка, обоснуйте, дождитесь голосования…

Я полагаю, что если бы вы формулировали свои мысли чуть более четко и чуть менее экспрессивно — минусов было бы меньше. Минусят не вашу точку зрения, а невозможность ее понять.

Никто вам лично не запрещает писать в стиле PHP3 под PHP7.1 (c учётом замены или даже полного выпиливания некоторых расширений, небольшого изменения поведения и прочих потерь совместимости). Но в целом, средние задачи за 20 лет усложнились и язык адаптируется к тому, чтобы их решение было проще. Причём средствами PHP. Тот же SQL (в чистом, максимально переносимом виде, без хранимых процедур, триггеров и т. п.) далеко не все задачи может решать, даже по фильтрации данных из базы, если фильтровать надо по значению, вычисленному по базе циклическим или рекурсивным алгоритмом. А вы тут возмущаетесь про итераторы, которые в языке появились более 10 лет назад и как раз позволяют использовать обычный олдскульный foreach для сложных задач.

Вы понимаете, что пришли критиковать огромную толпу народа и стоите ровно в её середине?

Существуют разные реализации и разные ситуации, когда тебе «в наследство» достается «код», который нужно здесь и сейчас подкрутить и чтобы оно быстро завелось. Бывает всякое и далеко не всегда можно все быстро «разрулить», и сделать как положено. В подобных ситуациях нужно знать расстояние для маневра.

А статья — отличная, впрочем, как и некоторые комментарии, что разъясняют для чего это надо.
Использование готовых итераторов и интерфейса IteratorAggregate позволяет нам значительно упростить создание собственных классов-итераторов.

результат будет таким же, как и при собственноручной реализации интерфейса Iterator.

Из статьи может показаться, что IteratorAggregate нужен только для готовых итераторов. Более точно: IteratorAggregate позволяет отделить код итератора от итерируемого объекта. И отличие такой реализации в том, что можно обходить один и тот же объект во вложенных foreach-циклах (т.к. итератор создается для каждого цикла свой).
Как обычно — комментарии более ценны, чем сама статья. Спасибо за дополнение!
НЛО прилетело и опубликовало эту надпись здесь
С версии 7.1
http://sandbox.onlinephpfunctions.com/code/4848817d5b26d623ebed8e4109aae49b064cd34b

Нет никаких причин не обновиться :)
НЛО прилетело и опубликовало эту надпись здесь
Всегда пожалуйста.
Фактически, такая запись — аналог оператора list, но чуть более умный. Можно, например, указывать, какой конкретно элемент (по ключу) в какую переменную будет развернут.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации