PHP 是正确的行为吗?

PHP is right behavior?

这对 php 来说是正确的行为吗?

PHP 版本 7.1.28PHP 版本 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"
}

为什么数组中的数据会发生变化?循环内没有变化。有解释吗?

没有错误。
您在两个循环中使用了相同的变量,但第一次是通过引用执行的,并且在循环后没有取消设置。 这意味着下次您更改变量时,您将更改源数组。
通过引用使用后取消设置。

$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

如果您查看自己的输出,您会在最后一项看到 &
这意味着它是参考。

在你的第二个 foreach 中,$label_item 是对 $label_list 的最后一个元素的引用,因此它会将 $label_list 的最后一个元素设置为值$label_list.

的第一个元素

为避免这种情况,只需在第二个 foreach 之前添加 unset($label_item) 以删除对 $label_list.

最后一个元素的引用

在没有参考的情况下工作。引用有很多陷阱。使用字段键更改字段元素。

$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); 
}