我刚刚通过php手册阅读了未设置的变量。
php手册说 “unset()销毁指定的变量”
这个def看起来很完美,直到我遇到静态变量... “如果函数内部的静态变量未设置(),则unset()仅在函数的其余部分的上下文中销毁变量。以下调用将恢复变量的先前值。”
这个定义对我来说似乎不是一个好的,至少,因为“销毁变量”意味着该变量不再与该内存位置相关联。
是否还有其他人认为更好的定义是“unset()使变量超出当前范围”?我的意思是,不是指向终生,而是在这里使用单词范围更好吗?
答案 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()
时,您只会销毁您创建的参考,而不是基础价值。
我没有确认,但我猜测会发生的是:
$bar
时,符号unset
与此zval相关联,其引用计数增加到2并且参考标志已设置。$bar
时,zval的引用计数减少为1,可能会清除引用标记并删除符号{{1}}。答案 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>