2017-04-20 112 views
0

我有一块PHP代码如下:修改数组值

foreach($collection as $key => $item) { 
    $collection[$key]['column'] = 'test'; 
    $item['column'] = 'test'; 
} 

当收集阵列具有超过30,000行,我得到这个错误PHP致命错误:允许的134217728存储器大小字节耗尽(试图分配89字节)。

如果我删除行$ collection [$ key] ['column'],forloop可以成功完成。

我不明白的是不是第2行和第3行基本相同?他们都在改变$ collection数组中的相同项目。

我在这里失踪了什么?使用这种

+1

实际上,修改$ item会创建一个副本并修改它,而不是$ collection(请参阅copy-on-write)。所以可能PHP是垃圾收集那些未使用的$ item,因此它不会耗尽你的内存,而不像添加到第2行的集合。我怀疑如果你要改变$ item到&$ item(导致改变为$项目更改$收集)在第1行,你会有同样的问题时,注释掉第2行。 – Christopher

回答

0

要回答你的问题,让我们先来快速浏览一下foreach docs

On each iteration, the value of the current element is assigned to $value and the internal array pointer is advanced by one (so on the next iteration, you'll be looking at the next element).

首先,让我们抓紧你的第一个问题,让我们把你的第二个问题。

What I cannot understand is that aren't line 2 and line 3 basically the same?

其实他们是不一样的,把这些简单的例子:

$array = ['a', 'a', 'a', 'a']; 

foreach ($array as $key => $value) { 
    $value = 'b'; 
} 

print_r($array); 
// Output : Array ([0] => a [1] => a [2] => a [3] => a) 

而在第二种情况:

$array = ['a', 'a', 'a', 'a']; 

foreach ($array as $key => $value) { 
    $array[$key] = 'b'; 
} 

print_r($array); 
// Output : Array ([0] => b [1] => b [2] => b [3] => b) 

所以,这是完全清楚,在你的第一种情况下,您已经修改了一些拷贝值或指定的值,并且没有触及实际值。

,所以我们可以说,-SO到speak-的foreach为PHP函数都有它自己的范围内,例如:

foreach ($array as $key => $value) { 
    // $value variable will be only visible here 
    // within the foreach context 
} 
echo $value; // will output Undefined variable 

They are both changing the same item in the $collection array.

你可以说 - 或承担 - 您已通过一个变量以值为单位进行foreach,因此在foreach文档中提到的php - - 修改了数组元素的副本,而不是实际值。

而在第二个示例中,您已修改数组$array的实际值,而不仅仅是其副本。

在我的例子而言,修改数组中的地方,你将需要通过你的变量的foreach by reference能够直接修改阵列值,例如:

$array = ['a', 'a', 'a', 'a']; 

foreach ($array as $key => &$value) { 
//      ^
    $value = 'b'; 
} 

print_r($array); 
// Output : Array ([0] => b [1] => b [2] => b [3] => b) 

让我们看一下你的另一个问题:

If I remove the line $collection[$key]['column'], the forloop can finish successfully.

这是因为上面提到的,你是通过你的变量按值的foreach,所以每次迭代OVE [R您30,000阵中还有三个操作PHP将执行: -

1)您的数组中的每个元素复制到另一个地方,在你的记忆
2)更新此复制件
3)更新您的收藏阵列

,我认为需要更多的内存,你的最大内存限制。

所以,作为Christopher在他的评论中提及,并作为foreach doc page提到:

In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.

传递你的价值参照可能会降低你的脚本的内存使用情况。

0

尝试:

ini_set('memory_limit', '-1'); 

这是不建议做,但你不时之需。这将覆盖默认的PHP内存限制。

+1

该op的问题是关于分配的差异,一个会导致内存问题,而不是其他,而不是避免内存问题总共... – Christopher

+0

但标题指出,内存变得枯竭。 –

+0

有一个内存泄漏,并知道为什么人需要发布整个代码。 –