2016-05-23 5 views
2

複数のforeachループと我々はすでに<code>foreach</code>知られているので

、各位へのちょうど別のメモリリークの話は痛みと頭痛があります。そして、それは我々が双子を持っている場合は血まみれの殺人マシンになるだろうか、行の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を使用しています。

yieldと問題はありません。戻る私のconcernationへhttps://stackoverflow.com/a/37342184/2932590

、私が最初にforeachの終わりにunset$parentObj$childrenObjの両方を試してみましたが、残念ながら:あなたはコードの懸念があれば、このサイト:)

の60K +プレイヤーが保証されています動いていない。私も参照&$parentDataを使用しようとしましたが、結果は同じです。

私の人生の残りの部分までこの仕事をすることができますか?

ありがとうございました。私は少数だ

を更新し

は、この場合にはSPLイテレータを使用することをお勧め。誰も私にそれがどのように動作するか説明してもらえますか?

ありがとうございました。私は以下、SPL Iteratorを使用しています#2

を更新し

新しいコードです:

$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(); 
} 

+0

あなたの質問は何ですか? – hkBst

+0

@hkBst:foreach内で複数のforeachとsaveオブジェクトを使用すると、PHPはエラーをスローします:許容されたメモリが使い果たされました.... –

+0

これで、行ごとにデータを読み込んでいるので、$でデータセット全体を再構築しようとしていますか? parentObj? – hkBst

答えて

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

私はこれを求めていません。 Btw、あなたのコードは 'IteratorIterator'なしで動作しないかもしれません –

0

SPLイテレータは一様なものではありませんしかしそれらの集合的な名前(標準のPHPライブラリイテレータ)。使用可能なものは全く異なって動作しますが、次のスタックオーバーフロースレッドは、すでにその使用方法や長所/短所を非常にうまく説明しようとしています。 PHP - Reasons to use Iterators?

+0

私は自分のメモリ使用量を減らす必要があります。だから私はイテレーターを選ぶのですが、それを作成する前にその質問を読んでいます。 –

0

おそらく$parentObj = $this->extract();は参照を使用せず、$parentObj->setData($childrenObj);は変更された各要素の初期配列からコピーを作成します。

別のアプローチがwhileループ内でポインタを移動することです:

reset($array); 
while (list($key, $val) = each($array)) { 
    $array[$key] = ++$val; 
    echo "$array[$key]\n"; 
} 
+0

これは動作しません。 –

+0

あなたが提供した情報に基づいて、配列を更新する方法に問題があるようです - [説明](http://stackoverflow.com/a/14854568/1539119)。より良いレスポンスを得るためには、少なくとも疑似コードでこれらのメソッド$ this-> extract()、$ parentObj-> setData($ childrenObj)、 'code' $ parentObj-> save()' code ' – Catalin

関連する問題