fclose
ハンドルを運ぶ変数の設定を解除するだけでコマンドを節約できるかどうか、少し困惑していますか?
$handle = fopen($file);
...
fclose($handle);
... // script goes on for a long
と比べて:
$handle = fopen($file);
...
unset($handle);
... // script goes on for a long
インサイト誰か?
PHP 4 の Zend Engine で導入された参照カウント システムのおかげで、リソースへの参照がなくなったリソースは自動的に検出され、ガベージ コレクターによって解放されます。
この意味を考えてみましょう。ガベージ コレクションの後、変数のすべての痕跡がなくなったと想定しても問題ありません。言い換えれば、PHP の実行の最後に、PHP がまだ参照を追跡していない場合、どのように参照を閉じるのでしょうか? したがって、ガベージ コレクターがそれを食べたときにそれを閉じることはかなり論理的に思えます。
これは、ガベージ コレクションが設定解除の直後または直後に発生し、PHP がユーザー ランドに存在しなくなった変数への非表示の参照を保持しないことを前提としているため、不適切な論理的議論です。
ただし、より説得力のあるケースは、ファイル ハンドルがスコープ外に出たときに PHP がファイル ハンドルを閉じなかった場合の潜在的な動作上の欠陥である可能性があります。多くのファイルを開くある種のデーモンを考えてみましょう。ここで、fclose が呼び出されないかどうかを検討してください。代わりに、変数がスコープ外になることを許可するか、変数に対して明示的に unset を呼び出します。
これらのファイル ハンドルが閉じられていない場合、この長時間実行されるデーモンはファイル ハンドルを使い果たします。
潜在的な動作固有のテスト スクリプト:
<?php
$db = mysql_connect(...);
if ($db) {
echo "Connected\n";
sleep(5); //netstat during this just for paranoia
unset($db);
echo "Unset\n";
sleep(5); //netstat during this and the connection is closed
}
Windows 7 と Debian 6 の両方で、設定解除後に接続が閉じられました。
明らかに、これは、特定の PHP バージョンを搭載した特定のマシンでこれが機能することを証明するだけです。ファイルハンドルなどには意味がありません:)。
ハードプルーフのためにPHPソースを検索しています
PHPのドキュメントは、参照が残っていないすべてのリソースが「解放」されることを示唆しています。ファイルハンドルの場合、これにはファイルを閉じることが含まれると思います。
簡単なテストケース:
$f = fopen("test.php", "r");
if (!flock($f, LOCK_EX)) {
print("still locked\n");
exit;
}
unset($f);
sleep(5);
print("goodbye\n");
(これをとして保存したtest.php
ので、それ自体がロックされています。そうでない場合は、のファイル名をfopen()
既存のファイルに変更する必要があるかもしれません)
スクリプトを5秒以内に2回実行します。「まだロックされている」場合は、ハンドルの設定を解除してもロックが解除されていないようです。私のテストでは、「まだロックされている」わけではないので、ハンドルの設定を解除すると、少なくともロックが解放されます。ただし、ガベージコレクション時にロックを解放するのはばかげているように見えますが、ファイルは閉じません。
unset($handle)
変数は破棄$handle
されますが、 が指すファイルは閉じられません$handle
。fclose()
ファイルを閉じるには、まだ呼び出す必要があります。
いくつかの研究:
fclose
し$handle
ているresource(5) of type (Unknown)
間
unset
それを作りますNULL
。
そしてfclose
phpが88バイト以上のメモリを消費した後。
だから:彼らは違う=)