11

PHPマニュアルで未設定の変数について読んだところです。

PHPマニュアルには、 「unset()は指定された変数を破棄する」と書かれています

この定義は、静的変数に遭遇するまで完璧に思えます... 「静的変数が関数内で unset() である場合、unset() は、関数の残りの部分のコンテキストでのみ変数を破棄します。次の呼び出しは、以前の変数を復元します。変数の値。」

この定義は、少なくとも私にとっては良いものではないようです。「変数を破棄する」は、変数がそのメモリ位置に関連付けられていないことを意味するからです。

「unset() は変数を現在のスコープから外します」というより良い定義を考えている人はいますか? つまり、寿命を指すのではなく、ここで単語スコープを使用する方が良いですか?

4

5 に答える 5

15

関数を考えてみましょう:

function foo() {
    static $bar;
    $bar++;
    unset($bar);
}
foo(); //static $bar is 1
foo(); //static $bar is 2

関数は次のようにコンパイルされます。

関数名: フー
操作数: 11
コンパイルされた変数: !0 = $bar
行番号 * op fetch ext return オペランド
-------------------------------------------------- -------------------------------
   2 0 > EXT_NOP                                                  
   4 1 EXT_STMT                                                 
         2 FETCH_W 静的 $0 'バー'
         3 ASSIGN_REF !0、$0
   5 4 EXT_STMT                                                 
         5 POST_INC ~1 !0
         6 無料 ~1
   6 7 EXT_STMT                                                 
         8 UNSET_VAR !0
   7 9 EXT_STMT                                                 
        10 > RETURN ヌル

変数は実際には への各関数呼び出しの外に存在しfoo()、呼び出しごとにフェッチされ、それへの参照が に割り当てられ$barます。実際、これは次のように非常によく似ています。

function foo() {
    global $bar;
    $bar++;
    unset($bar);
}

を呼び出すとunset()、基になる値ではなく、作成した参照のみが破棄されます。

確認はしていませんが、次のようなことが起こると思います。

  • 変数 (zval) の基になる表現は、その参照カウントが 1 になるように格納されます。
  • foo()呼び出されると、シンボル$barがこの zval に関連付けられ、その参照カウントが 2 に増え、参照フラグが設定されます。
  • unset呼び出されると、zval の参照カウントが 1 に減少し、参照フラグはおそらくクリアされ、シンボル$barは削除されます。

参照カウントの基本を参照してください。

于 2010-07-06T21:39:21.197 に答える
9

関数内では、静的変数を参照する変数名はまさに..参照です。実際には、unset は参照を破棄します。

于 2010-07-06T20:12:57.390 に答える
4

unset(self::$somethingstatic); 変数が静的であるため、致命的なエラーが発生します (常にそこにあり、設定を解除することはできません)。

ドキュメントは、関数内で定義された静的変数を具体的に参照しています。以下を考慮してください。

function t($stage)
{
  static $shell = 23;
  switch($stage) {
    case 1:
      $shell++;
      break;
    case 2:
      unset($shell);
      break;
    case 3:
      $shell--;
    break;
  }
  echo $shell;
}

$shell は静的変数であるため、常に存在する (静的) ため、単に参照である $shell に言及するときはいつでも - 設定を解除すると、参照の設定が解除されます (シンボリック リンクのリンク解除を考えてください) - 静的変数ただし、まだそこにあります(これが static の意味です)。

したがって、上記の関数を呼び出すと、t(1) は 24 をエコーし​​、t(2) は何もエコーせず、t(3) は (正しく) 23 をエコーし​​ます:)

助けて?

于 2010-07-06T20:27:18.720 に答える
0

さて、unset()変数名に関連付けられたメモリをクリアします。

ただし、静的変数の場合、静的変数が関数のスコープから分離され、関数を呼び出すたびに、その変数のコピーが自動的に取得されます。

したがって、これが意味することはunset、静的変数の場合、実際にはunsetそのコピーのみを使用しているため、関数が再度呼び出されると、新しいコピーを「受け取る」ということです。

于 2010-07-06T20:32:54.150 に答える