php中引用的数组迭代导致奇怪的结果

时间:2017-05-04 09:11:34

标签: php arrays reference iteration

我看到了一些我不太了解的奇怪行为。我做了以下事情:

$array = [
    'a' => [
        'a1' => [
            'a11' => 1,
            'a12' => 2
        ],
        'a2' => [
            'a21' => 3,
            'a22' => 4
        ],
    ],
    'b' => [
        'b1' => [
            'b11' => 1,
            'b12' => 2
        ],
        'b2' => [
            'b21' => 3,
            'b22' => 4
        ],
    ],
];

foreach ($array as $strLevel1 => &$arrLevel1)
{
    foreach ($arrLevel1 as $strLevel2 => &$arrLevel2)
    {
        foreach ($arrLevel2 as $strLevel3 => &$varLevel3)
        {
            $varLevel3 = 0;
        }
    }
}

echo '<pre>';
var_dump($array);
echo '</pre>';

foreach ($array as $strLevel1 => $arrLevel1)
{
}

echo '<pre>';
var_dump($array);
echo '</pre>';

结果如下:

array(2) {
  ["a"]=>
  array(2) {
    ["a1"]=>
    array(2) {
      ["a11"]=>
      int(0)
      ["a12"]=>
      int(0)
    }
    ["a2"]=>
    array(2) {
      ["a21"]=>
      int(0)
      ["a22"]=>
      int(0)
    }
  }
  ["b"]=>
  &array(2) {
    ["b1"]=>
    array(2) {
      ["b11"]=>
      int(0)
      ["b12"]=>
      int(0)
    }
    ["b2"]=>
    &array(2) {
      ["b21"]=>
      int(0)
      ["b22"]=>
      &int(0)
    }
  }
}
array(2) {
  ["a"]=>
  array(2) {
    ["a1"]=>
    array(2) {
      ["a11"]=>
      int(0)
      ["a12"]=>
      int(0)
    }
    ["a2"]=>
    array(2) {
      ["a21"]=>
      int(0)
      ["a22"]=>
      int(0)
    }
  }
  ["b"]=>
  &array(2) {
    ["a1"]=>
    array(2) {
      ["a11"]=>
      int(0)
      ["a12"]=>
      int(0)
    }
    ["a2"]=>
    array(2) {
      ["a21"]=>
      int(0)
      ["a22"]=>
      int(0)
    }
  }
}

如您所见,在第一个输出中一切正常。但是在第二个中,数组的b-named分支被a-named分支取代。这是因为我做了引用。如果我把“&amp;”在最后一个循环中的$ arrLevel1之前,它再次起作用。

为什么?我对参考文献做错了吗?或者我应该根本不使用它们并且仅在没有任何参考的情况下完全限定数组操作?

提前致谢。

1 个答案:

答案 0 :(得分:1)

也许你应该在循环之后取消设置$arrLevel1的引用,直到你为第二个循环重用var。

foreach ($array as $strLevel1 => &$arrLevel1)
{
    foreach ($arrLevel1 as $strLevel2 => &$arrLevel2)
    {
        foreach ($arrLevel2 as $strLevel3 => &$varLevel3)
        {
            $varLevel3 = 0;
        }
    }
}

// remove reference
unset($arrLevel1);

echo '<pre>';
var_dump($array);
echo '</pre>';

foreach ($array as $strLevel1 => $arrLevel1)
{
}

echo '<pre>';
var_dump($array);
echo '</pre>';

绕过unset的方法是为循环变量使用唯一的名称,或者 - 如果要再次循环同一个数组 - 也可以使用引用循环变量。

foreach ($array as $strLevel1 => &$arrLevel1)
{
    foreach ($arrLevel1 as $strLevel2 => &$arrLevel2)
    {
        foreach ($arrLevel2 as $strLevel3 => &$varLevel3)
        {
            $varLevel3 = 0;
        }
    }
}

// also use a reference
foreach ($array as $strLevel1 => &$arrLevel1)
{
}

大多数情况下,如果不使用引用或在“原子”中移动循环可能会更简单。只进行操作并返回结果的函数。