関数を考えてみましょう:
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
は削除されます。
参照カウントの基本を参照してください。