Недавно я испытал эту странную проблему:
while(list($key, $value) = each($array))
не перечислял все значения массива, заменив их на …
foreach($array as $key => $value)
… работал отлично.
И теперь мне интересно. В чем разница между этими двумя?
Раньше вы проходили массив? each()
запоминает свою позицию в массиве, поэтому, если вы не reset()
вы можете пропустить предметы.
reset($array); while(list($key, $value) = each($array))
Ибо то, что стоит этот метод обхода массива, древний и был заменен более идиоматическим foreach. Я бы не использовал его, если вы специально не хотите использовать его по одному пункту по времени.
массив каждый ( массив и $ массив)
Верните текущую пару ключей и значений из массива и продвиньте курсор массива.
После выполнения
each()
курсор массива будет оставлен на следующем элементе массива или за последним элементом, если он попадает в конец массива. Вы должны использоватьreset()
если хотите снова пересечь массив, используяeach
.
(Источник: Руководство PHP )
Ну, одна разница в том, что each()
будет работать только с массивами (ну, только правильно работает). foreach
будет работать на любом объекте, который реализует интерфейс с возможностью traversable
(что, конечно, включает встроенный тип массива).
В foreach может быть микро-оптимизация. В принципе, foreach эквивалентен следующему:
$array->rewind(); while ($array->valid()) { $key = $array->key(); $value = $array->current(); // Do your code here $array->next(); }
В то время как each
основном выполняет следующие действия:
$return = $array->valid() ? array($array->key(), $array->current()) : false; $array->next(); return $return;
Таким образом, три строки одинаковы для обоих. Они оба очень похожи. Могут быть некоторые микро-оптимизации в том, что each
не нужно беспокоиться об traversable
интерфейсе … Но это будет в лучшем случае незначительным. Но это также будет компенсировано выполнением логического литья и проверки в php-коде vs foreach
скомпилированного C … Не говоря уже о том, что в ваш момент while/each
код вы вызываете две языковые конструкции и одну функцию, тогда как с foreach
это единая языковая конструкция …
Не говоря уже о том, что foreach
намного более читаемо ИМХО … Так что легче читать, и более гибко означает, что для меня – это лучший победитель. (это не означает, что у each
нет его использования, но лично я его никогда не нуждался) …
Предупреждение! Foreach создает копию массива, поэтому вы не можете изменять ее, пока foreach выполняет итерацию по ней . each()
все еще есть цель и может быть очень полезно, если вы делаете живые изменения в массиве, перебирая его элементы и индексы.
// Foreach creates a copy $array = [ "foo" => ['bar', 'baz'], "bar" => ['foo'], "baz" => ['bar'], "batz" => ['end'] ]; // while(list($i, $value) = each($array)) { // Try this next foreach($array as $i => $value) { print $i . "\n"; foreach($value as $index) { unset($array[$index]); } } print_r($array); // array('baz' => ['end'])
с// Foreach creates a copy $array = [ "foo" => ['bar', 'baz'], "bar" => ['foo'], "baz" => ['bar'], "batz" => ['end'] ]; // while(list($i, $value) = each($array)) { // Try this next foreach($array as $i => $value) { print $i . "\n"; foreach($value as $index) { unset($array[$index]); } } print_r($array); // array('baz' => ['end'])
Оба foreach
и while
закончат их петли, и массив « $array
» будет изменен. Однако цикл foreach не изменялся, когда он был циклическим, поэтому он все еще повторялся по каждому элементу, хотя мы удалили их.
Я думал, что этот ответ был довольно прост, но, похоже, большинство пользователей здесь не в состоянии оценить конкретные детали, которые я упоминаю здесь.
Разработчики, которые создали приложения, использующие libdom (например, удаление элементов) или другие интенсивные фильтры map / list / dict, могут подтвердить важность того, что я сказал здесь.
Если вы не поймете этот ответ, он укусит вас когда-нибудь.
Если вы передали each
объект для повторения, руководство по PHP предупреждает, что оно может иметь неожиданные результаты.
Что именно находится в $array