PHP это правильное поведение? - PullRequest
0 голосов
/ 14 октября 2019

Правильно ли это поведение для php?

, протестированного на PHP версии 7.1.28 и PHP версии 7.2.13 Почему список изменился? Это ошибка PHP или я чего-то не знаю?

$label_list = explode(',', '1111, 22222, 33333');
foreach($label_list as &$label_item) {
    $label_item = trim(mb_strtolower($label_item));
}

var_dump($label_list); // source list
foreach ($label_list as $label_item) {
    var_dump($label_list); //? wtf list
}

данные результата:

array(3) {
  [0]=> string(4) "1111"
  [1]=> string(5) "22222"
  [2]=> &string(5) "33333"
}
array(3) {
  [0]=> string(4) "1111"
  [1]=> string(5) "22222"
  [2]=> &string(4) "1111"
}
array(3) {
  [0]=> string(4) "1111"
  [1]=> string(5) "22222"
  [2]=> &string(5) "22222"
}
array(3) {
  [0]=> string(4) "1111"
  [1]=> string(5) "22222"
  [2]=> &string(5) "22222"
}

Почему данные в массиве изменяются? без изменений внутри цикла. Любое объяснение?

Ответы [ 3 ]

2 голосов
/ 14 октября 2019

Нет ошибки.
Вы использовали одну и ту же переменную в обоих циклах, но в первый раз вы делали это по ссылке и не сбрасывали ее после цикла. Это означает, что при следующем изменении переменной вы изменяете исходный массив.
Сбрасывается после использования по ссылке.

$label_list = explode(',', '111, 222, 333');
foreach($label_list as &$label_item) {
    $label_item = trim(mb_strtolower($label_item));
}
unset($label_item); // unset the by reference variable
var_dump($label_list); // source list
foreach ($label_list as $label_item) {
    var_dump($label_list); //? wtf list
}

Выходы:

array(3) {
  [0]=>
  string(3) "111"
  [1]=>
  string(3) "222"
  [2]=>
  string(3) "333"
}
array(3) {
  [0]=>
  string(3) "111"
  [1]=>
  string(3) "222"
  [2]=>
  string(3) "333"
}
array(3) {
  [0]=>
  string(3) "111"
  [1]=>
  string(3) "222"
  [2]=>
  string(3) "333"
}
array(3) {
  [0]=>
  string(3) "111"
  [1]=>
  string(3) "222"
  [2]=>
  string(3) "333"
}

https://3v4l.org/MjlcU

Если вы посмотрите на свой собственный вывод, вы увидите & на последнем элементе.
Это означает, что это по ссылке.

0 голосов
/ 14 октября 2019

Работа без ссылок. Ссылки имеют много подводных камней. Используйте ключи поля для изменения элементов поля.

$label_list = explode(',', '1111, 22222, 33333');
foreach($label_list as $key => $label_item) {
    $label_list[$key] = trim(mb_strtolower($label_item));
}

var_dump($label_list); // source list
foreach ($label_list as $label_item) {
    var_dump($label_list); 
}
0 голосов
/ 14 октября 2019

В вашем втором foreach, $label_item - ссылка на последний элемент $label_list, поэтому последний элемент $label_list будет установлен со значением первого элемента $label_list. * 1006. *

Чтобы избежать этого, просто добавьте unset($label_item) перед вторым foreach, чтобы удалить ссылку на последний элемент $label_list.

...