#php #arrays
#php #массивы
Вопрос:
Я тестирую производительность / помехи для ссылок на копии массива. У меня есть следующий код:
function ScoreWords($Value){
$WordList = array(
"Amazing" => 1,
"Value" => 300,
"Elements" => 30,
"Another" => 0
);
if (array_key_exists($Value,$WordList)){
return $WordList[$Value];
}
}
$array = ["Value","Another",1,2,3,4];
echo implode(',', $array), "<br>";
foreach ($array as amp;$value) {
ScoreWords($value);
}
echo implode(',', $array), "<br>";
foreach ($array as $value) {
ScoreWords($value);
}
echo implode(',', $array), "<br>";
Но, похоже, вставленный выше код работает почти нормально. Вывод:
Значение, Другое, 1,2, 3, 4
Значение, Другое, 1,2, 3, 4
Значение, Другое, 1,2,3,3
Я нашел это по ошибке, поскольку в сжатии на самом деле не было необходимости, но это вызывает вопрос. Почему для окончательной печати дублируется значение, а не правильное значение 4
? независимо от того, каково содержимое массива. Кажется, что он дублирует второй от последнего элемент в качестве последнего элемента?
Комментарии:
1. Прочитайте # 1 в этом списке из 10 наиболее распространенных ошибок, которые совершают PHP-программисты
2. @MarkBaker: Вау. Это прекрасно объясняет точную проблему здесь! 😀
Ответ №1:
Что происходит, так это то, что после вашего 1-го foreach
, $value
есть ссылка на последний элемент в массиве. По мере выполнения этого цикла это была ссылка на каждый элемент, пока, наконец, не остановилась на последнем.
Итак, при foreach
запуске 2-го, $value
это все еще ссылка. По мере выполнения этого цикла он обновляется $value
, что, в свою очередь, обновляет последний элемент в массиве.
Когда дело доходит до последнего элемента, ему было присвоено значение 3 из предыдущей итерации цикла. Итак, вот почему в конце установлено значение 3.
Чтобы исправить это, unset($value);
после вашего первого foreach
.
Комментарии:
1.
var_dump($array)
покажет, что элемент действительно является ссылкой
Ответ №2:
Дело здесь в том, что вам нужно unset
указывать значение, когда вы передаете его по ссылке:
foreach ($array as amp;$value) {
ScoreWords($value);
}
unset($value); // break the reference with the last element
Предупреждение о том, что ссылка на значение $ и последний элемент массива остаются четными
после цикла foreach. Рекомендуется уничтожить это с помощью unset() .