Let's consider the function:
function foo() {
static
bar++;
unset($bar);
}
foo(); //static $bar is 1
foo(); //static $bar is 2
The function compiles to:
function name: foo
number of ops: 11
compiled vars: !0 = $bar
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_NOP
4 1 EXT_STMT
2 FETCH_W static $0 'bar'
3 ASSIGN_REF !0, $0
5 4 EXT_STMT
5 POST_INC ~1 !0
6 FREE ~1
6 7 EXT_STMT
8 UNSET_VAR !0
7 9 EXT_STMT
10 > RETURN null
A variable actually exists outside each function call to foo() and, on each call, it's fetched and a reference to it is assigned to $bar. In fact, it's very similar to this:
function foo() {
global
bar++;
unset($bar);
}
When you call unset(), you're only destroying the reference you created, not the underlying value.
I didn't confirm, but what I'd guess that happens is this:
- The underlying representation of the variabe (the zval) is stored so that its reference count is 1.
- When
foo()is called, the symbol$baris associated with this zval, its reference count is increased to 2 and the reference flag is set. - When
unsetis called, the zval has its reference count decreased to 1, the reference flag is probably cleared and the symbol$baris removed.
See reference count basics.
Answer from Artefacto on Stack OverflowVideos
Let's consider the function:
function foo() {
static
bar++;
unset($bar);
}
foo(); //static $bar is 1
foo(); //static $bar is 2
The function compiles to:
function name: foo
number of ops: 11
compiled vars: !0 = $bar
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_NOP
4 1 EXT_STMT
2 FETCH_W static $0 'bar'
3 ASSIGN_REF !0, $0
5 4 EXT_STMT
5 POST_INC ~1 !0
6 FREE ~1
6 7 EXT_STMT
8 UNSET_VAR !0
7 9 EXT_STMT
10 > RETURN null
A variable actually exists outside each function call to foo() and, on each call, it's fetched and a reference to it is assigned to $bar. In fact, it's very similar to this:
function foo() {
global
bar++;
unset($bar);
}
When you call unset(), you're only destroying the reference you created, not the underlying value.
I didn't confirm, but what I'd guess that happens is this:
- The underlying representation of the variabe (the zval) is stored so that its reference count is 1.
- When
foo()is called, the symbol$baris associated with this zval, its reference count is increased to 2 and the reference flag is set. - When
unsetis called, the zval has its reference count decreased to 1, the reference flag is probably cleared and the symbol$baris removed.
See reference count basics.
Inside a function, variable names referencing static variables are just that.. references. In effect, unset destroys the reference.