我们都听说过在for
循环中我们应该这样做:
for ($i = 0, $count = count($array); $i < $c; ++$i)
{
// Do stuff while traversing array
}
而不是:
for ($i = 0; $i < count($array); ++$i)
{
// Do stuff while traversing array
}
出于性能原因(即初始化$count
只会调用count()
一次,而不是每次有条件检查都调用count()
。
如果在foreach
循环中执行此操作,那么它是否会产生影响:
$array = do_something_that_returns_an_array();
foreach ($array as $key => $val)
{
// Do stuff while traversing array
}
而不是:
foreach (do_something_that_returns_an_array() as $key => $val)
{
// Do stuff while traversing array
}
假设情况允许我使用?也就是说,PHP在这两种情况下只调用一次函数,还是像for
那样第二种情况会一次又一次地调用函数?
答案 0 :(得分:38)
foreach()
是implemented using iterators - 因此它只调用一次返回数组的函数,然后使用指向现有结果集的迭代器继续每个项目。
答案 1 :(得分:9)
我认为测试它肯定会回答这个问题。
这是我的代码:
function GetArray() {
echo "I am called.\n";
return array("One"=>1, "Two"=>2, "Three"=>3, "Four"=>4, "Five"=>5);
}
echo "Case #1\n";
$array = GetArray();
foreach ($array as $key => $val){
// Do stuff while traversing array
echo " Inside the loop: $key => $val\n";
}
echo "\n";
echo "Case #2\n";
foreach (GetArray() as $key => $val) {
// Do stuff while traversing array
echo " Inside the loop: $key => $val\n";
}
echo "\n";
以下是结果:
Case #1 I am called. Inside the loop: One => 1 Inside the loop: Two => 2 Inside the loop: Three => 3 Inside the loop: Four => 4 Inside the loop: Five => 5 Case #2 I am called. Inside the loop: One => 1 Inside the loop: Two => 2 Inside the loop: Three => 3 Inside the loop: Four => 4 Inside the loop: Five => 5
他们都读了一次通话功能。所以没有什么不同。
答案 2 :(得分:8)
foreach
制作输入数组的副本,并在每次迭代中处理它。因此,您可以使用foreach (do_something_that_returns_an_array() as $key => $val)
,并且只会调用do_something_that_returns_an_array()
一次。
答案 3 :(得分:4)
我会举一个例子来看看会发生什么。有点像...
function do_something_that_returns_an_array() {
echo 'I have been called!';
return array('i am an', 'array');
}
答案 4 :(得分:2)
我一直认为do_something_that_returns_an_array()
只运行一次,因为与for循环不同,它没有理由多次运行。 for循环真值检查器在每次迭代结束时运行的原因是允许非常复杂的检查器。
作为测试,我做了以下事情:
function get_array() {echo 5; return array(1,2,3,4,5);}
foreach(get_array() as $key => $value) {}
脚本打印5次。因此,函数get_array()
仅评估一次。
答案 5 :(得分:0)
foreach()与Iterator或IteratorAggregate对象(例如,实现接口的数组和对象)一起使用。它不能与不可变对象一起使用。函数返回不可变对象,因此返回数组必须在foreaching之前复制到Iterator对象中(由php本身制作)