PHP 是正确的行为吗?
PHP is right behavior?
这对 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"
}
为什么数组中的数据会发生变化?循环内没有变化。有解释吗?
没有错误。
您在两个循环中使用了相同的变量,但第一次是通过引用执行的,并且在循环后没有取消设置。
这意味着下次您更改变量时,您将更改源数组。
通过引用使用后取消设置。
$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"
}
如果您查看自己的输出,您会在最后一项看到 &
。
这意味着它是参考。
在你的第二个 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);
}
这对 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"
}
为什么数组中的数据会发生变化?循环内没有变化。有解释吗?
没有错误。
您在两个循环中使用了相同的变量,但第一次是通过引用执行的,并且在循环后没有取消设置。
这意味着下次您更改变量时,您将更改源数组。
通过引用使用后取消设置。
$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"
}
如果您查看自己的输出,您会在最后一项看到 &
。
这意味着它是参考。
在你的第二个 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);
}