Ответ 1
Почему он не переопределяет значение массива во время итерации?
foreach будет работать над копией исходного массива, поэтому все, что вы измените в цикле foreach, не изменит значения, которые вы зацикливаете.
У меня есть сомнение в итерации php foreach.
Посмотрите мой код ниже.
КОД:
$arr=array(1,2,3);
echo '$arr value : '. $arr;
echo '<br>';
foreach($arr as $arr){
echo $arr.'<br>';
}
echo '$arr value : '. $arr;
ВЫХОД:
$arr value : Array
1
2
3
$arr value : 3
В то время как итерационный массив я использовал одно имя массива для значения ключа foreach($arr as $arr)
, но он отлично работает. Как это работает?
Почему он не переопределяет значение массива во время итерации?
Я хочу знать, как работает итерация foreach.
Пожалуйста, помогите мне!
Спасибо заранее Логан
Почему он не переопределяет значение массива во время итерации?
foreach будет работать над копией исходного массива, поэтому все, что вы измените в цикле foreach, не изменит значения, которые вы зацикливаете.
PHP использует механизм copy on write
или lazy copy
с подсчет ссылок для обработки памяти.
На первом этапе итерации foreach $arr
"мягко скопирован" (фактическая копия отсутствует, но увеличивается только refcount
zval
of $array
). checkout variable container
и label
переменных PHP.
В нашем случае
$arr
, и первое значение массива извлекается из контрольной точки.$arr
foreach ($ arr как $arr)$arr
и продолжается.$arr
изменяется внутри цикла, вы не можете распечатать этот массив вне цикла с помощью переменной $arr
.Надеюсь, вы поймете...
Для углубленного изучения проверки http://www.php.net/manual/en/internals2.opcodes.fe-fetch.php и http://www.php.net/manual/en/internals2.opcodes.fe-reset.php
Интересно, что вы тоже можете играть с этим...
current()
внутри цикла foreach всегда возвращает тот же элемент!!!
код
$source = array(10, 20, 30);
foreach ($source as $value) {
echo 'Value is ', $value, ', and current() is ', current($source), '<br>';
}
Выход
Value is 10, and current() is 20
Value is 20, and current() is 20
Value is 30, and current() is 20
foreach ($arr as $arr) {
// code
}
Это может вас смутить, потому что ваша ментальная модель того, как это работает:
$arr
и продвигает указатель массива$arr
// code
Что это на самом деле делает, хотя это (или, по крайней мере, приблизительное упрощение):
foreach
, беря значение массива, связанное с $arr
var iterator
var iterator
и продвигает итератор$arr
в script// code
Другими словами, на каждой итерации он не принимает следующее значение из $arr
, оно используется только один раз для получения начального итератора. Фактическая вещь, которую он выполняет, хранится внутри и больше не связана с $arr
. Это означает, что $arr
является бесплатным для других целей в вашем script, и PHP с удовольствием повторно использует его на каждой итерации. После завершения цикла последний элемент остается в $arr
.
Если вы знаете анонимные функции, возможно, это лучше иллюстрирует, почему это работает так, как это работает:
foreach($arr, function ($arr) {
// code
});
Реализация такой функции foreach
может быть просто следующей:
function foreach(array $array, callable $code) {
while (list(, $value) = each($array)) {
$code($value);
}
}
$arr и $arr одинаковы в вашем коде. Массив источника и ссылочная переменная имеют одинаковое имя. Так что foreach сохраняет значение, которое было получено последним, оно не отбрасывает переменную.
foreach
используйте копию исходного массива, чтобы вы могли подумать о коде
foreach($arr as $arr){
echo $arr.'<br>';
}
выглядит так:
for ($i = 0, $arr_tmp = $arr, $len = count($arr_tmp); $i < $len; $i++) {
$arr = $arr_tmp[$i];
echo $arr.'<br>';
}
Это объясняет, почему $arr
- 3
.
вы закончите запись массива при извлечении записи, вы просите код извлечь запись из $arr и поместить ее в массив с именем $arr, чтобы вы закончили запись всего массива с помощью одного параметра до $ arr = {1,2,3}; после этой строки и первой итерации foreach ($ arr as $arr) теперь $arr равен 3, который является последним элементом массива, надеюсь, вы столкнулись с проблемой
Хмм, после небольшого исследования я придумал этот код:
<?php
$arr=array(1,2,3);
echo '$arr value : '. $arr;
echo '<br>';
foreach($arr as $arr){
echo $arr.'<br>';
}
foreach($arr as $key) {
echo $key.'<br>';
}
echo '$arr value : '. $arr;
Который имел этот вывод:
$arr value : Array
1
2
3
PHP Warning: Invalid argument supplied for foreach() in ...file...
Я читал об этом, что второй $arr
затеняет первый внутри цикла foreach
, но как только он выходит из цикла foreach
, он внутренне отключает символ ($arr
)
foreach
сначала оценивает левую сторону перед повторением своих элементов. Поэтому переназначение на имя $arr не изменяет $arr.
Кроме того, переменная цикла течет во внешний контекст, поскольку документально:
Ссылка a
$value
и последний элемент массива остаются даже после цикла foreach. Рекомендуется уничтожить его unset().
Конечно, чтобы избежать путаницы, вы должны просто использовать другое имя для переменной цикла, чем для массива, который вы зацикливаете:
$arr=array(1,2,3);
foreach($arr as $a) { // Note the "as $a", not "as $arr"
echo $a.'<br>';
}
echo '$arr value : '. $arr;