Подтвердить что ты не робот

Как считывается массив в цикле foreach PHP?

Мы все слышали о том, как в цикле 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, где второй случай будет вызывать функцию снова и снова?

4b9b3361

Ответ 1

foreach() реализован с использованием итераторов - поэтому он вызывает только функцию, возвращающую массив один раз, а затем использует итератор, который указывает на существующий набор результатов будет продолжен с каждым элементом.

Ответ 2

Я думаю, что тестирование это обязательно ответит.

Вот мой код:

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

Они оба читают функцию вызова один раз. Так что ничего другого.

Ответ 3

foreach делает копию входного массива и работает на нем на каждой итерации. Таким образом, вы можете использовать foreach (do_something_that_returns_an_array() as $key => $val), и он будет вызывать do_something_that_returns_an_array() только один раз.

Ответ 5

Я всегда предполагал, что do_something_that_returns_an_array() работает только один раз, потому что, в отличие от цикла for, нет причин для его запуска несколько раз. Причина, по которой средство проверки истинности цикла работает в конце каждой итерации, - это позволить очень сложным шашкам.

В качестве теста я сделал следующее:

function get_array() {echo 5; return array(1,2,3,4,5);}
foreach(get_array() as $key => $value) {}

script напечатано 5 раз. Поэтому функция get_array() оценивается только один раз.

Ответ 6

foreach() работает с объектами Iterator или IteratorAggregate (например, массивами и объектами, реализующими интерфейс). Он не может работать с неизменяемыми объектами. Функции возвращают объекты неизменяемые, поэтому возвращаемый массив должен быть скопирован в объект Iterator перед тем, как он будет отправлен (сделанный самим php)