Странная печать на массивах

#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() .

Ссылка на каждый