2011-02-03 1 views
17
for($i=0; $i<3; $i++) { 
    echo '$i = ' . $i . '<br/>' ; 
} 
echo 'out of loop, $i = ' . $i; 

上記出力:なぜPHPはループを離れるとメモリをクリアしませんか?

$i = 0 
$i = 1 
$i = 2 
out of loop, $i = 3 

それは$私もループ範囲の外にそれを表示した後まだ見えであるように私には意味がありません。なぜこれが起こるのですか(Javaでは自動的にガベージコレクションされます)?

そして、に自動的にPHPを伝える方法はありますか?は、ループスコープから出た後にガベージコレクションを行いますか?各ループの後にunset()と呼ぶ必要があるとき、私のコードは醜いように見えます。

+9

これは機能です。メソッドの外_Every_変数/: – Arvin

+20

PHPは、うん必要なしGC、http://us2.php.net/manual/en/language.variables.scope.php –

+0

ません関数はグローバルです。これは特に、メソッド(/evilReiko)がメソッド/関数の中でループする場合、あなたの変数を 'unset()'する必要はないということを意味します。 –

答えて

42

これは、スコープについてです、ガベージコレクションではありません。 PHPで

、ループは、独自のスコープを作成しないために。 $iはループと同じスコープ内で作成されるため、ループが終了してもまだ存在します。ループの前にあなたが宣言している変数以上にガベージコレクションされることはありません。それは多くの場合、1つとして使われているよう

は、機能として考えてください。たとえば、ループの前にループカウンタを宣言して、ループから抜け出した後の値を知る必要はありません。

変数unsetを手動で実行すると、gc_collect_cyclesで強制的にガベージコレクションを行うことができます。

+0

ただ、ほかよりもその優れた@マークのjava – KingCrunch

+2

このように(実際には99.999%のケースで)わかりやすい例では、GCを呼び出す必要はなく、推奨することさえあります。たぶん、スクリプトの生涯の早い段階で巨大なデータ構造を使って作業しているのであれば、おそらくそうでない場合はおそらくもっと良いでしょう。 – fwielstra

8

Variable scope

から変数のスコープは、それが定義された範囲内のコンテキストです。ほとんどの場合、すべてのPHP変数は1つのスコープしか持たない。この1つのスコープは、インクルードされたファイルと必要なファイルにまたがっています。 [...]ユーザ定義関数内に、ローカル関数スコープが導入されています。関数内で使用される変数は、デフォルトではローカル関数スコープに制限されています。

ループを離れるとスコープ内にまだ$iという参照があるため、変数はガベージコレクトされません。 unsetを使用すると、ガベージコレクションは行われませんが、GCが次に実行されるときに収集されるGarbage Collectorで参照されなくなったメモリのみをマークします。 gc_collect_cyclesでガベージコレクションを強制することができます。

4

あなたは、変数の上で左をクリアする必要があるループを置き換えるために再帰関数を使用している場合。

ちょうどちょうどにし、そこからデータを渡し、別の関数で、それは別のスコープにする必要がありますいずれかのループを置きます。

+0

興味深い回避策! – evilReiko

関連する問題