我有一段php代码如下:
foreach($collection as $key => $item) {
$collection[$key]['column'] = 'test';
$item['column'] = 'test';
}
当集合数组有超过30,000行时,我收到此错误PHP致命错误:允许的内存大小为134217728字节耗尽(尝试分配89字节)。
如果我删除了行$ collection [$ key] ['列'],则forloop可以成功完成。
我无法理解的是,第2行和第3行基本相同吗?它们都在更改$ collection数组中的相同项目。
我在这里缺少什么?
答案 0 :(得分:0)
尝试使用:
ini_set('memory_limit', '-1');
建议不要这样做,但在你需要的情况下。这将覆盖默认的PHP内存限制。
答案 1 :(得分:0)
要回答您的问题,我们先来快速浏览一下foreach docs
在每次迭代时,将分配当前元素的值 $ value和内部数组指针先进一步(所以在 下一次迭代,你将看到下一个元素。)
首先让我们提出你的第一个问题,让我们回答你的第二个问题。
我无法理解的是,基本上不是第2行和第3行 一样吗?
实际上它们并不相同,请采取那些简单的例子:
$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 )
所以,完全清楚的是,在你的第一种情况下,你已经修改了一些复制值或指定值,可以这么说,并没有触及实际值。
所以我们可以说 - 也就是说 - 因为php函数具有它自己的上下文,例如:
foreach ($array as $key => $value) {
// $value variable will be only visible here
// within the foreach context
}
echo $value; // will output Undefined variable
他们都在更改$ collection数组中的相同项目。
你可以说 - 或假设 - 你已经通过值传递变量到foreach,所以php - 如foreach docs 中提到的 - 修改过数组元素的副本,而不是实际值。
在第二个示例中,您已经修改了数组$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 )
让我们转到你的另一个问题:
如果我删除了行$ collection [$ key] ['列'],那么forloop可以 顺利完成。
这是因为如上所述,您将变量传递给foreach by value,因此对于30,000
数组的每次迭代,php将执行三个操作: -
1)将阵列中的每个元素复制到记忆中的另一个位置
2)更新此复制的元素
3)更新你的集合数组
我认为你的最大内存限制需要更多的内存。
所以,正如Christopher
在评论中提到的那样,以及foreach doc page中提到的那样:
为了能够直接修改循环内的数组元素 使用&前面的$ value。在这种情况下,值将由 参考
通过引用传递您的值可能会减少脚本的内存使用量。