Comments 19
foreach ($test AS &$value) {
// какие-то действия. Но для теста и пустого цикла достаточно
}
думаю что эти «какие-то действия» как раз и изменили в Вашем примере значение с ключом 5
// какие-то действия. Но для теста и пустого цикла достаточно
}
думаю что эти «какие-то действия» как раз и изменили в Вашем примере значение с ключом 5
unset надо делать…
ua2.php.net/manual/ru/control-structures.foreach.php
Особенно стоит обратить внимание на:
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
Особенно стоит обратить внимание на:
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
попробуйте так:
$test = array('1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5);
foreach ($test AS &$value) {
// какие-то действия. Но для теста и пустого цикла достаточно
}
unset($value);
print_r($test);
foreach ($test AS $key => $value) {
echo "{$key} => {$value}\n";
}
Да, это помогает. Но механизм все равно не понятен. Почему имеено последняя итерация ссылается на предпоследний элемент? Почему не первая?
после первового foreach'а $value является ссылкой на последний элемент массива
во втором foreach'е происходит следующее:
на первой итерации $value присваивается значение первого элемента массива (а значит и его последнему элементу тоже), то есть массив уже выглядит так: 1 2 3 4 1
на второй итерации $value=2, то бишь массив — 1 2 3 4 2
на третьей итерации — 1 2 3 4 3
на четвертой — 1 2 3 4 4
а на пятой — пятому элементу массива присваивается значение пятого (а сейчас 5 элемент — 4)
вот как-то так
во втором foreach'е происходит следующее:
на первой итерации $value присваивается значение первого элемента массива (а значит и его последнему элементу тоже), то есть массив уже выглядит так: 1 2 3 4 1
на второй итерации $value=2, то бишь массив — 1 2 3 4 2
на третьей итерации — 1 2 3 4 3
на четвертой — 1 2 3 4 4
а на пятой — пятому элементу массива присваивается значение пятого (а сейчас 5 элемент — 4)
вот как-то так
Довольно неожиданно, но я думаю что это как-то объясняется (ведь интерпритатор руководствуется какой-то логикой?).
ОФФ. Цикл foreach плохо влияет на производительность — во время прогона элементов он создает в памяти копию исходного массива и оперирует с ней, после чего удаляет (цитата с php.net «foreach operates on a copy of the specified array and not the array itself»). Вместо него лучше-таки использовать while:
while(list($key, $val) = each($array)){… } reset($array);
ОФФ. Цикл foreach плохо влияет на производительность — во время прогона элементов он создает в памяти копию исходного массива и оперирует с ней, после чего удаляет (цитата с php.net «foreach operates on a copy of the specified array and not the array itself»). Вместо него лучше-таки использовать while:
while(list($key, $val) = each($array)){… } reset($array);
Не удобно. А экономить на спичках глупо.
Экономия на спичках — это замена двойных кавычек на одинарные (например). А тут, если исходный массив будет несколько мегабайт, то создавать его копию уже точно не умно.
Но не будем спорить :) Спасибо за фишку, буду знать теперь!
Но не будем спорить :) Спасибо за фишку, буду знать теперь!
Как я понимаю, копия делается только по требованию. По крайней мере ни раз читал, что копия аргументов функции делается толко при попытке изменить их. Было бы логично в циклах сделать так-же.
Тут уже проскакивала не раз ссылка на phpbench.com
Так вот там утверждается что для чтения foreach примерно в 5-7 раз быстрее чем while (list… each..)
А вот если вы собираетесь изменять исходный массив, то тут конечно foreach сильно отстает.
Так вот там утверждается что для чтения foreach примерно в 5-7 раз быстрее чем while (list… each..)
А вот если вы собираетесь изменять исходный массив, то тут конечно foreach сильно отстает.
это давнейший богус: bugs.php.net/bug.php?id=29992
[8 Oct 2004 8:54am UTC] derick@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
www.php.net/manual/ and the instructions on how to report
a bug at bugs.php.net/how-to-report.php
Right, thanks for that analysis. No bug here. (And no, we can't unset it
by default, as people might use this for some weird reason).
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
www.php.net/manual/ and the instructions on how to report
a bug at bugs.php.net/how-to-report.php
Right, thanks for that analysis. No bug here. (And no, we can't unset it
by default, as people might use this for some weird reason).
Я бы назвал эту статью «будьте внимательнее с указателями»
Sign up to leave a comment.
Осторожнее с итерацией массивов по ссылке