Я пытаюсь провести рефакторинг большого старого проекта, и я заметил одну вещь - ряд различных реализаций Iterator:
while($iterator->moveNext()) {
$item = $iterator->current();
// do something with $item;
}
for($iterator = getIterator(), $iterator->HasNext()) {
$item = $iterator->Next();
// do something with $item
}
while($item = $iterator->fetch()) {
// do something with item
}
или даже итератор StandardPHPLibrary (SPL), который позволяет
foreach($iterator as $item) {
// do something with $item
}
Наличие такого количества разных итераторов (с разными методами перебора коллекций) кажется сильным запахом кода, и я склонен реорганизовать все до SPL. Есть ли у любой из этих реализаций Iterator неоспоримое преимущество, или это просто вопрос личного вкуса?






Версия SPL определенно подходит. Его не только легче всего читать, но и теперь он является частью PHP, поэтому он будет знаком гораздо большему количеству людей.
В остальных нет ничего «плохого», но, как вы сказали, наличие всех этих разных версий в одном проекте никому не помогает.
Imo, простое использование одной или нескольких библиотек SPL в качестве интерфейса имеет тенденцию быть менее уродливым в использовании во внешнем интерфейсе. Однако поддержка реализации может стать немного некрасивой.
Например, я написал итератор, который эффективно повторял набор результатов базы данных, так что результаты, которые никогда не запрашивались, никогда не извлекались из указателя запроса, и если элементы были извлечены преждевременно (IE: $ obj [5]), он будет искать все требуемые результаты во внутренний буфер.
Работая замечательно, вы просто молитесь, чтобы код, который заставляет закулисную магию никогда не давать сбоев, потому что он сбивает людей с толку, когда они видят, что вы используете что-то похожее на массив, и он творит «волшебство», которое может потерпеть неудачу :)
Магия сжигала людей на кострах. Так что используйте его осторожно и с умом, возможно, сделайте очевидным, как он работает.
Лично я предпочитаю
for( $object as $i => $v )
обозначения для него, как правило, более последовательны и предсказуемы.
for( $dbresult->iterator() as $i => $v ){
}
нотация стиля функционально идентична, но, по крайней мере, у вас меньше догадок, как это работает на поверхности.