多个foreach循环和另一个内存泄漏故事

时间:2016-05-23 10:27:58

标签: php memory-management memory-leaks foreach

可能关注的人,

我们已经知道foreach是一个痛苦而且令人头痛的问题,而我们使用它来处理战争或数百万的记录。如果我们有一对双胞胎,或者可能连续foreach更多,它将成为一个血腥的杀手机器。)

例如,

foreach ($parent as $parentData) {
    // few conditional added here
    $parentObj = $this->extract();
    foreach ($chilren as $childrenData) {
        if ($childrenData['id'] === $parentData['id']) {
            $childrenObj = $this->extract();
            $parentObj->setData($childrenObj);
            // and even more evil things come here....
        }
    }
    $parentObj->save();
}

在我的情况下,我有两个foreach。每个包含大约50,000~70,000条记录。 $parent$children是传递给方法的参数。

$parent$children的原始数据源都是CSV文件。我正在使用yield将其转换为可以使用foreach传播。

yield没有问题,相信我。这个网站的60k +玩家可以保证:)

如果您关注代码:https://stackoverflow.com/a/37342184/2932590

回到我的观察,我在第一个unset结束时尝试$parentObj $childrenObjforeach,但遗憾的是它不起作用。我也尝试使用引用&$parentData,但结果是一样的。

我怎么能在我的余生中完成这项工作?

感谢高级。

已更新

在这种情况下,我很少被建议使用SPL迭代器。任何人都可以解释一下它是如何工作的吗?

感谢。

更新#2

我正在使用SPL Iterator,下面是新代码:

$parent = new IteratorIterator(new ArrayIterator($parentArr));
$children = new IteratorIterator(new ArrayIterator($chilrenArr));
foreach ($parent as $index => $parentData) {
    $parentObj = null;
    // few conditional added here
    $parentObj = $this->extract();
    $childrenObj = null;
    foreach ($chilren as $key => $childrenData) {
        if ($childrenData['id'] === $parentData['id']) {
            $childrenObj = $this->extract();
            $parentObj->setData($childrenObj);
            // and even more evil things come here....
        }
    }
    $parentObj->save();
    $childrenObj->save();
}

3 个答案:

答案 0 :(得分:0)

使用SPL迭代器:

// create a new ArrayIterator and pass in the array
$parentDataIter = new ArrayIterator($parentData);

// loop through the object one item at a time memory-wise
foreach ($parentDataIter as $key => $value) {
    // ...
}

答案 1 :(得分:0)

SPL迭代器不是统一的东西,而只是它们的集合名称(标准PHP库迭代器)。可用的工作方式完全不同,但下面的堆栈溢出线程已经尝试很好地解释它们的用途和优点/缺点。 PHP - Reasons to use Iterators?

答案 2 :(得分:0)

可能, for(i=0; i<=100; i+=1){ drawPie(".pies", 100, i, "orange"); } </script> </body> </html> 不使用引用,$parentObj = $this->extract();使PHP从初始数组为每个更改的元素创建一个副本。

另一种方法是在$parentObj->setData($childrenObj);循环中移动指针:

while