foreach循环和&$ value的引用

Kha*_*lid 21 php arrays foreach

为什么空的foreach循环可以改变结果.

我有以下代码:

$variable = [1,2,3,4];
foreach ($variable  as $key => &$value) 
  $value ++;

var_dump($variable);
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

array (size=4)
  0 => int 2
  1 => int 3
  2 => int 4
  3 => &int 5
Run Code Online (Sandbox Code Playgroud)

现在,当我像这样添加一个空的foreach循环时:

$variable  = [1,2,3,4];
foreach ($variable  as $key => &$value) 
  $value ++;

foreach ($variable  as $key => $value);
  var_dump($variable);
Run Code Online (Sandbox Code Playgroud)

我明白了:

array (size=4)
  0 => int 2
  1 => int 3
  2 => int 4
  3 => &int 4
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下为什么当我添加第二个空循环时最后一个元素不会改变,以及为什么最后一个元素有一个&infront?

Ade*_*mar 13

在第一个循环结束时,$value指向与它们相同的位置$variable[3](它们指向内存中的相同位置):

$variable  = [1,2,3,4];
foreach ($variable  as $key => &$value) 
    $value ++;
Run Code Online (Sandbox Code Playgroud)

即使这个循环完成,$value仍然是一个指向内存中相同位置的引用$variable[3],因此每次存储一个值时$value,这也会覆盖存储的值$variable[3]:

foreach ($variable as $key => $value);
var_dump($variable);
Run Code Online (Sandbox Code Playgroud)

有了这个的foreach的每一个评价,无论是$value$variable[3]正在成为等于迭代项目在$变量的值.

所以在第二个循环的第3次迭代中,$value并且$variable[3]通过引用变为等于4,那么在第二次循环的第4次和最后一次迭代期间,没有任何变化,因为你将$variable[3](仍然是&$value)的值传递给$value(它仍然是&$value).

这很令人困惑,但它甚至都不是特别的; 这是完全按照应有的方式执行的代码.

更多信息:PHP:通过参考传递

  • 这不是语言缺陷吗?$value 变量对于 foreach 循环应该是本地的,并且不能从外部访问。 (2认同)

Ale*_*ukh 11

这是一个名称冲突:第一个循环中引入的名称$值存在于它之后,并在第二个循环中使用.因此,对它的所有赋值实际上都是对原始数组的赋值.您在此代码中更容易观察到您所做的事情:

  $variable = [1,2,3,4];
  foreach ($variable  as $key => &$value) 
    $value ++;
  $value = 123; // <= here you alter the array!
  var_dump($variable);
Run Code Online (Sandbox Code Playgroud)

你会看到$variable[3]123.

正如其他人所说,避免这种情况的一种方法是unset ($value)在循环之后,这应该是手册建议的良好做法.另一种方法是在第二个循环中使用另一个变量:

  $variable  = [1,2,3,4];
  foreach ($variable  as $key => &$value) 
    $value ++;
  foreach ($variable  as $key => $val);
  var_dump($variable);
Run Code Online (Sandbox Code Playgroud)

这不会改变你的阵列.

  • @AlexanderGelbukh我一直以为自己!幸运的是,当PHP编写良好时,这些问题可以通过数据封装和范围最小化,但不幸的是PHP通常写得不好...... (2认同)

Avi*_*abu 5

即使在foreach循环之后,数组的最后一个元素也会重新启动.所以它需要unset在循环外使用函数..那就是

$variable  = [1,2,3,4];
  foreach ($variable  as $key => &$value) {
$value++;


}
  unset($value);
  var_dump($variable); 
Run Code Online (Sandbox Code Playgroud)

可在此处找到手册的链接http://php.net/manual/en/control-structures.foreach.php