私も PHP の学習者ですが、これまでは、コード内で unset、null、mysql_close、__destruct などの関数を使用して、メモリ オーバーフローを防ぐためにオブジェクトを解放するだけでした。私はインターネット上の GG で次の手順を見つけて記録しました: 「PHP は自動的にメモリを管理し、不要になったオブジェクトを消去できます。PHP は参照カウントと呼ばれる単純なガベージ コレクション メカニズムを使用します。各オブジェクトに参照カウンターが含まれるたびに、各参照はオブジェクトに接続されます。参照がリビング スペースから離れるか、NULL に設定されると、カウンターは 1 ずつ減ります。オブジェクトの参照カウンターがゼロになると、PHP はこのオブジェクトがゼロになることを認識します。必要になり、それが占有しているメモリ空間が解放されます。「
ご存知のとおり、PHP エンジン自体は C で書かれています。C について言及するときは、GC (ガベージ コレクション) について言及する必要があります。PHP マニュアルを読むと、PHP エンジンが GC アクションを自動的に実行することがわかります。」これは正確に何をするのでしょうか? unset() が変数を unset() するために使用されるとき、それは本当にリサイクルされますか?しかし、注意深く分析してみると、決して単純で一般的なものではないことがわかります。おそらく誰かが「PHP のソース コードを見ればわかります。PHP を読み通せばわかります。」と言うかもしれません。ただし、この記事では、PHP 自体の一見普通だがよく使われる問題のみを分析します。もちろん、私のレベルが限られているため、いくつかの詳細を見落としていることは避けられません。省略しました。皆さんを温かく歓迎します。
phper について一緒に説明します。
まず、最も単純な実行プロセスの例を見てみましょう。
例 1: gc.php
error_reporting(E_ALL);
$a = 'I am test.'; $b = & $a;
echo $b ." ";
?> 言うまでもなく、出力結果は非常に明確です:
hy0kl% php -f gc.php
OK、次:
例 2:
error_reporting(E_ALL);
$b = & $a;
$b = '変更します。 ;
echo $a ." ";
?>
hy0kl% php -f gc.php
変更しますか?見てみましょう:
error_reporting(E_ALL);
$a = '私はテストです。';
unset($a); " ";
echo $b ." ";
それについて考える必要がありますか?
hy0kl% php -f gc.php
注意: /usr/local/www/apache22/ に未定義の変数がありますdata/test /gc.php の 8 行目
私はテストです。
少し混乱していますか?
例 4:
error_reporting(E_ALL);
$b = & $a ;
unset($b);
echo $a ." ";
?> 実際、例 3 を理解していれば、これは例 3 と同じです。 f gc.php
私は test です
注意: 未定義の変数: /usr/local/www/apache22/data/test/gc.php の 9 行目
例 5:
error_reporting(E_ALL);
$b = & $a = null; '. $a ." ";
echo '$b = '. $b .";
hy0kl% php -f gc.php
$a b =
はい、これが出力結果です。PHP GC を深く理解している PHP 愛好家にとっては、このコードを初めて実行したときは驚きましたが、今では不思議に思いました。 PHP GC についてより深く理解していると、それを使用する次の例は自然に理解しやすくなります。
例 6:
error_reporting(E_ALL);
$a = '私はテストです。';
$b = & $a;
echo '$a = '。 ." ";
echo '$b = '.$b ." ";
?>
OK、上記の例の結果に詳細が含まれていない場合は、このウィンドウを閉じても構いません。時間があるときにまた来てください!
GC と参照を詳しく分析してみましょう
1. すべての例で、このプロセスはメモリ内にスペースを開き、そこに文字列 I を格納します。 . am test.. PHP 内にはメモリの各ブロックの参照数を記録するシンボル テーブルがあり、このとき、このメモリ ブロックの参照数は 1 ずつ増加し、$a という名前のラベル (変数) が作成されます。はこのメモリ ブロックを指すため、タグ名に従ってメモリを簡単に操作できます。
2. 変数 $a に対して & 演算を実行します。私の理解では、$a が指すメモリを見つけて、$b に同じ参照点を確立し、テスト対象の文字列のメモリ ブロックを保存します。つまり、スクリプトがこの行を実行すると、文字列 I am test を格納するメモリが 2 回参照されることになります。ここで強調すべき点は、& 操作が PHP のポインタではなく参照ポイントを確立するということです。にはポインタの概念がありません。同時に、UNIX と同様のファイル ソフト リンクを提案している人もいます。これは、私たちのテストの実際のファイルであることをある程度理解できます。 $aと
$b は実ファイルに対して確立されたソフト リンクですが、同じ実ファイルを指しているため、例 2 で $b に値が割り当てられると、特定の A を通じて $a の値も変化することがわかります。ソフトリンクも同様にファイルを操作します。
3. 例 3 と 4 では、unset() 操作が実行されました。実際の実行結果によれば、unset() は、変数の参照を元のメモリに切断するだけであることがわかります。変数自体が未定義であるため、null 参照が渡された場合、呼び出し時に通知が発行され、シンボル テーブル内のそのメモリ部分の参照カウントが 1 減算され、この部分を指す他の変数には影響しません。つまり、メモリの一部がシンボル テーブルに参照カウントを持っている場合にのみ、それが 0 の場合、PHP エンジンはこのメモリを再利用します。
PHP マニュアル
4.0.0 unset() は式になりました (PHP 3 では、unset() は常に 1 を返します)
次のコードとその結果を見てください:
error_reporting (E_ALL);
$a = '私はテストです。';unset($a);
unset($a);
echo '$b = '。 >
hy0kl% php -f gc.php
注意: 未定義の変数: /usr/local/www/apache22/data/test/gc.php の 10 行目
$a =
$b = 私はテストです。
最初の unset() 操作でポインターが切断されたため、後続の操作はシンボル テーブル内のメモリの参照カウントに影響を与えません。 null を割り当てる操作は、変数が指すメモリのシンボル番号の参照カウントを直接 0 に設定することになるため、このメモリはエンジンによって自然に再利用されることは明らかです。どのようにそれが再び使用されるかは不明です。他の情報をすぐに保存するために使用される可能性もありますが、いずれにせよ、そのメモリ部分を指す元の変数はすべて動作できなくなります。再利用されたメモリでは、変数を呼び出そうとすると null が返されます。
error_reporting(E_ALL);
$a = '私はテストです。';
$b = null;
echo '$b = '. $b ." ";
if (null === $a)
{
echo '$a は null です。'; else
{
echo '$a の型は不明。';
?>
hy0kl% php -f gc.php
$a =
$b =
$a が null である理由を要約すると、open のソース コードを調べている理由が完全に説明されています。ソース製品では、比較的大きな一時変数や、使用後に呼び出されなくなった再利用された情報が集中するか、null として表示されることがよくあります。これは、UNIX で実際のファイルを直接強制終了し、すべてのソフト リンクをポイントするのと同じです。当然空の鎖になった
以上、PHP の参照渡しについて内容も含めて紹介しましたが、PHP チュートリアルに興味のある友人の参考になれば幸いです。