【问题标题】:Looping in array changes element type数组中的循环更改元素类型
【发布时间】:2020-01-12 04:39:59
【问题描述】:

考虑一下这个在数组中循环的 PHP 代码 sn-p 按值引用

$arr = [1 ,2 , 3];
var_dump($arr);
echo '<br>';

foreach ($arr as &$val) { // note ampersand sign
   // Anything
}

var_dump($arr);

现在首先 var_dump() 发出

array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

但是第二次发射

array(3) { [0]=> int(1) [1]=> int(2) [2]=> &int(3) }

因此,通过引用在数组中循环已经改变了最后一个值类型 - 从整数到整数 reference ! 怎么可能呢?为什么 PHP 决定自己更改元素类型而开发人员无意这样做?

【问题讨论】:

  • foreach之后执行unset($val)
  • $a = &amp;$b; 使两个变量都成为参考。这就是你的 foreach 所做的 - $val=$arr[0] 然后 $val =& $arr[1]....
  • 我知道取消设置 $val 或更改变量名会有所帮助。但问题不在于这个。 WTF,为什么中间变量会影响数组元素存储?我要求解释这种奇怪的行为或背后的理由

标签: php arrays pass-by-reference


【解决方案1】:

要了解这种行为,您需要了解一些关于 PHP 的知识:

  • PHP 中的引用是对称的:您不是“创建对变量的引用”,而是“将变量添加到引用集中”。
  • 引用的foreach 与引用的一系列赋值相同,一个接一个。
  • 数组值本身被视为变量,并且可以具有所有相同的类型信息,包括作为参考集的一部分。

让我们“展开”你的循环:

// create a reference set containing $val and $arr[0]
$val =& $arr[0];
// remove $val from the first reference set, 
// and create a second reference set containing $val and $arr[1]
$val =& $arr[1];
// remove $val from the second reference set, 
// and create a third reference set containing $val and $arr[2]
$val =& $arr[2];

此时,$arr[0]$arr[1] 都在大小为 1 的参考集中,因此可以看作是“正常值”。但是,$arr[2] 仍然在与 $val 的引用集中。

这意味着对$arr[2] 的任何更改都将反映在$val 中,而$val 的任何更改将反映在$arr[2] 中。这就是为什么var_dump&amp; 注释该项目,以表明更改它也会更改其他地方的另一个变量。

这就是为什么在使用 foreach-by-reference 之后总是运行 unset($val); 是一个好习惯。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 2011-08-04
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    相关资源
    最近更新 更多