11

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?

Austin Hyde
  • 26,347
  • 28
  • 96
  • 129
Tarun
  • 3,162
  • 3
  • 29
  • 45
  • This is not a good question for SO. You can state such things in PHP mailinglists or whatever, but it has no value here. What would you expect from an answer? Are you satisfied if I say *Yes* ? ;) – Felix Kling Jul 06 '10 at 20:14
  • 2
    felix, i am just a beginner if you wld say yes it wld surely boost my confidence and if you say no then surely wld learn something,but from next i wld take care of this.thankz – Tarun Jul 06 '10 at 20:25

5 Answers5

15

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.

Artefacto
  • 96,375
  • 17
  • 202
  • 225
9

Inside a function, variable names referencing static variables are just that.. references. In effect, unset destroys the reference.

Zak
  • 24,947
  • 11
  • 38
  • 68
  • you meant to say i declare a static variable as(consider inside a fn) static $a=2; $b=$a+2;//here $a become refernce of static variable $a;? i didn,t get you point sir – Tarun Jul 06 '10 at 20:31
  • For static variables, space is allocated on the heap for the data value, and space is allocated on the stack for the reference link. When unsetting a reference, only the local stack space is destroyed/reclaimed/made invalid. – Zak Jul 06 '10 at 21:44
4

unset(self::$somethingstatic); will raise an Fatal error, because the variable is static (always there, can't be unset).

the documentation refers specifically to static variables defined inside a function, consider:

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

because $shell is a static variable, it's always there (static) so any other time you mention $shell that is simply a reference - when you unset it, you are unsetting the reference (think unlink'ing a symlink) - the static variable is however still there (that's what static means).

thus if you call the above function t(1) will echo 24, t(2) will echo nothing, and t(3) will (rightly) echo 23 :)

help any?

nathan
  • 5,402
  • 1
  • 22
  • 18
  • i wld love to say "any other time you mention $shell that is simply a reference:"but AFAIK ..in php memory is allocated even for reference??correct me – Tarun Jul 06 '10 at 20:41
  • thankz nathan i din,t know abt unsetting static property ll give error – Tarun Jul 07 '10 at 14:13
1

If am not wrong, the point is to unset a static variable. For different reasons this might be useful, in addition this would free some memory. For example:

unset($some_static_var_or_property_holding_a_big_object);

While we cannot achive this exactly as is, in some cases could be enough to do this:

$some_static_var_or_property_holding_a_big_object = null;

This would free some memory (I guess) and would allow us to destroy an object we don't want anymore (I hope I am not out off topic).

Melsi
  • 1,462
  • 1
  • 15
  • 21
0

Well, what unset() does is clears up the memory associated with a variable name.

In the case of static variables, however, what you can visualize as happening is separating the static variable from the scope of the function, and every time you call the function, you automatically get a copy of that variable.

So, what this means is if you unset a static variable, you are only actually unsetting that copy, so when the function is called again, it "receives" a fresh copy.

Austin Hyde
  • 26,347
  • 28
  • 96
  • 129
  • whats wrong if i just visualize that unset() kick the variable out of scope,now wheather it clear up the memroy associated with variable or not it depend on the lifetime of variable. – Tarun Jul 06 '10 at 21:02
  • well, the problem with what you're saying is that realistically, a `static` declared variable is not *in* the scope of the function, and that's why it carries over from call to call. OTOH, you're on the right track if you consider that it's the copy of that static variable that you are "kicking out of scope" – Austin Hyde Jul 07 '10 at 13:39