2016-10-28 10 views
4

foreachを使用している場合、アレイを操作することによる安全性の影響について、数多くの質問があります。しかし、私はwhileループでこれを行う上で疑問を見つけることはできません。whileループで配列に追加することは安全ですか?

だから、これをするのが安全でしょうか?以下はPHPのサンプルスクリプトですが、これが問題ないかどうかはわかりません。

while ($item = array_pop($array)) { 
    findMoreItems($item, $array); 
} 

function findMoreItems($item, &$array) { 
    // Returns null if no more items are found 
    $newItem = someFuncFromServer($item); 

    if ($newItem) { 
    array_push($array, $newItem); 
    } 
} 

私は、ループ内の項目がスキップされていないことを確認できますか?コードが何をしているようなコピー参照または配列ポイントか何かのような何もしないであろうことは明らかである上記の方法でこれを書き換える場合は今

$item = array_pop($array); 
while ($item) { 
    findMoreItems($item, $array); 
    $item = array_pop($array) 
} 

function findMoreItems($item, &$array) { 
    // Returns null if no more items are found 
    $newItem = someFuncFromServer($item); 

    if ($newItem) { 
    array_push($array, $newItem); 
    } 
} 

+8

無限ループと同じくらい安全です。 – apokryfos

+3

この質問は、意外にも、見た目よりもはるかに深いです。私はそれを説明することができますが、私はそれを十分に説明していないでしょう。初心者は[ここ](https://nikic.github.io/2011/11/11/PHP-Internals-When-does-foreach-copy.html)をご覧ください。[ここ](http://stackoverflow.com/質問/ 3307409/php-pass-by-foreach)と[here](https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make)を参照してください。それは複雑ではありませんが、正しく説明するのは難しいことです。そして無限ループではない@apokryfos。 – Andrew

+0

"潜在的な"無限ループです。 –

答えて

1

あなたのコードは、本質的に同等ですforeachです。 foreachは、array_poparray_pushが含まれていない内部配列ポインタに依存しているためです。

+0

結局のところ、このことがどのように間違っているのかを考える方法はありません。 foreachに関するあなたの答えは正しい。合理的には完全に安全です。 エラーが発生する可能性がありかどうかを確認するために、データの全体の多くといくつかの実際の寿命試験を駆動するために興味深いものになるだろうが - PHPは、予期しない動作をしない場合は念のために。 – Blackbam

+0

私はもっと大きなリスクは 'someFuncFromServer'のバグが無限ループになる可能性があるということです。 – apokryfos

関連する問題