PHP:在foreach循环后,替换数组值不会停留

时间:2011-07-19 22:05:54

标签: php multidimensional-array foreach

我正在更改多维数组中的值,并且它不会停留在用于遍历它的foreach循环之外。

我的数组最初看起来像这样:

Array
{
  [0] => Array
   {
     [name] => Bob
     [age] => 33
     [state] => CA
     [visited] => 0
   }
   ...
}

我的PHP进入它:

foreach ($people as $person){
 echo $person['name']
 ....
 logic for the visited variable
 ...
 $person['visited'] = $calculated_visit_value;
}

如果我

print_r($person)
在foreach循环的结尾(但在里面)

一切看起来都很好,访问的值设置了。但是,如果我在循环外print_r($people),则未设置$person['visited']。我不知道我做错了什么。

非常感谢帮助。

4 个答案:

答案 0 :(得分:37)

您正在从for循环中创建一个名为$person的新变量,您的数组永远不会看到该新变量的范围。

您可以尝试通过引用传递它,如下所示:

foreach ($people as &$person){
 echo $person['name'];
 ....
 logic for the visited variable
 ...
 $person['visited'] = $calculated_visit_value;
}

答案 1 :(得分:3)

来自foreach's documentation

  

除非引用了数组,否则foreach将对其进行操作   指定的数组而不是数组本身。 foreach有一些方面   对数组指针的影响。在此期间不要依赖数组指针   或者在没有重置之后使用foreach。

这意味着,你的$人变量是什么阵,实际上类似这样的代码复印件(请注意,这个代码仅与错是了解在许多层面上,在现实中你会使用复位(),current()和next()函数在数组see here)上正确循环:

for ($i = 0; $i < count($people); $i++) {
  $person = $people[$i];
  // code inside your foreach ...
}

因此,如果您更改$ person的内容,则实际上并未修改$ people数组中的内容

要解决这个问题,您可以使用引用的foreach:

foreach ($people as &$person) { // note the &
  $person = $calculated_visit_value; // $person is now a reference to the original value inside $people and thus this will work as intended
}

请注意,当foreach循环结束时,refence不会被清除,所以在$ end结束时,$ person仍然是对$ people的最后一个元素的引用。 如果您不知道哪些参考文献,请参阅the documentation了解更多信息。

或使用密钥访问原始数组:

foreach ($people as $person_index => $person) {
  $people[$person_index] = $calculated_visit_value;
}

为了您的信息,您可以一起使用这两个

foreach ($people as $person_index => &$person { ...

答案 2 :(得分:0)

每次迭代都会生成$person数组,因此无论如何都要设置该值。

但即便如此,该数组仅在循环期间存在。您应该在循环之前创建另一个数组,并在循环期间将值放入该数组中。

答案 3 :(得分:0)

正如已经被告知的那样,“你正在从for循环中创建一个名为$ person的新变量,你的数组永远不会看到那个新变量的范围。”

我发现这个解决方案更加强大:

foreach ($people as $key => $person)
{
  echo $person['name']; 

  //logic for the visited variable

  $people[$key]['visited']=$calculated_visit_value;
}