最近我遇到了这个奇怪的问题:
while(list($key, $value) = each($array))
未列出所有数组值,将其替换为...
foreach($array as $key => $value)
......工作得很好。
而且,我现在很好奇......这两者有什么区别?
答案 0 :(得分:51)
你之前是否已经遍历了阵列? each()
会记住它在数组中的位置,所以如果你没有reset()
,你就会错过项目。
reset($array);
while(list($key, $value) = each($array))
值得一提的是,这种数组遍历的方法很古老,并且被更惯用的foreach所取代。我不会使用它,除非你特别想要利用它的一次性项目。
数组 每个(数组& $数组)
从数组中返回当前键和值对并使数组光标前进。
执行
each()
后,数组游标将保留在数组的下一个元素上,如果它到达数组的末尾则超过最后一个元素。如果要使用reset()
再次遍历数组,则必须使用each
。
(资料来源:PHP Manual)
答案 1 :(得分:12)
嗯,一个区别是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代码与foreach
编译的C进行抵消...更不用说在while/each
代码中,你要调用两种语言结构和一个函数,而foreach
它是一个单一的语言结构...
更不用说foreach
更具可读性恕我直言......更容易阅读,更灵活意味着 - 对我来说 - foreach
是明显的赢家。 (这并不是说each
没有它的用途,但我个人从来不需要它......)
答案 2 :(得分:8)
警告! 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
和while
都会完成循环,数组“$array
”将会更改。但是,foreach循环在循环时没有改变 - 所以即使我们删除它们,它仍然会遍历每个元素。
我认为这个答案很简单,但看来这里的大多数用户都无法理解我在这里提到的具体细节。
使用libdom构建应用程序的开发人员(如删除元素)或其他密集的map / list / dict过滤可以证明我在这里所说的重要性。
如果你不理解这个答案,它会在某一天咬你。
答案 3 :(得分:1)
如果您通过each
对象进行迭代,PHP手册会警告它可能会有意外结果。
$array