在php中取消设置变量

时间:2010-07-06 20:07:57

标签: php static unset

我刚刚通过php手册阅读了未设置的变量。

php手册说 “unset()销毁指定的变量”

这个def看起来很完美,直到我遇到静态变量... “如果函数内部的静态变量未设置(),则unset()仅在函数的其余部分的上下文中销毁变量。以下调用将恢复变量的先前值。”

这个定义对我来说似乎不是一个好的,至少,因为“销毁变量”意味着该变量不再与该内存位置相关联。

是否还有其他人认为更好的定义是“unset()使变量超出当前范围”?我的意思是,不是指向终生,而是在这里使用单词范围更好吗?

5 个答案:

答案 0 :(得分:13)

让我们考虑一下这个功能:

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

该函数编译为:

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

变量实际存在于foo()的每个函数调用之外,并且在每次调用时,它都被提取并且对$bar的引用被分配给function foo() { global $bar; $bar++; unset($bar); } 。事实上,它与此非常相似:

unset()

当您致电foo()时,您只会销毁您创建的参考,而不是基础价值。

我没有确认,但我猜测会发生的是:

  • 存储变量的基础表示(zval),使其引用计数为1.
  • 当调用$bar时,符号unset与此zval相关联,其引用计数增加到2并且参考标志已设置。
  • 调用$bar时,zval的引用计数减少为1,可能会清除引用标记并删除符号{{1}}。

请参阅reference count basics

答案 1 :(得分:9)

在函数内部,引用静态变量的变量名只是..引用。实际上,取消设置会破坏参考。

答案 2 :(得分:3)

未设置(自:: $ 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只是一个引用 - 当你取消它时,你没有设置引用(想想取消链接一个符号链接) - 然而,静态变量仍然存在(这就是静态的意思)。

因此如果你调用上面的函数t(1)将回显24,t(2)将不回显,而t(3)将(正确)回显23:)

帮助任何人?

答案 3 :(得分:1)

如果没有错,重点是取消静态变量。由于不同的原因,这可能是有用的,此外这将释放一些内存。例如:

unset($some_static_var_or_property_holding_a_big_object);

虽然我们无法完全按照原样实现这一点,但在某些情况下可能足以做到这一点:

$some_static_var_or_property_holding_a_big_object = null;

这会释放一些记忆(我猜)并且会让我们破坏一个我们不再需要的对象(我希望我不会偏离主题)。

答案 4 :(得分:0)

嗯,unset()做的是清除与变量名相关联的内存。

但是,对于静态变量,您可以将其视为正在发生的事情是将静态变量与函数范围分开,并且每次调用该函数时,都会自动获得该变量的副本。

所以,这意味着如果你unset是一个静态变量,你实际上只是unset那个副本,所以当再次调用该函数时,它会“接收”一个新的副本。 / p>