unset variable in php

Tarun picture Tarun · Jul 6, 2010 · Viewed 16.9k times · Source

I just read about unset variable through php manual.

The php manual says "unset() destroys the specified variables"

This def seems perfect until I came across static variable... "If a static variable is unset() inside of a function, unset() destroys the variable only in the context of the rest of a function. Following calls will restore the previous value of a variable. "

This definition doesn't seems a good one for me, at least, since "destroy the variable" implies that the variable is no longer associated with that memory location.

Does anyone else think a better definition would be "unset() makes the variable out of current scope"? I mean, rather than pointing towards lifetime, it's better to use word scope here?

Answer

Artefacto picture Artefacto · Jul 6, 2010

Let's consider the function:

function foo() {
    static $bar;
    $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;
    $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 $bar is associated with this zval, its reference count is increased to 2 and the reference flag is set.
  • When unset is called, the zval has its reference count decreased to 1, the reference flag is probably cleared and the symbol $bar is removed.

See reference count basics.