在 PHP 中,所有值都保存在所谓的 s 中。这些包含实际数据,类型信息和 - 这对您的问题很重要 - 参考计数。请看以下代码段:zval
zval
$a = new B; // $a points to zval(new B) with refcount=1
$b = $a; // $a, $b point to zval(new B) with refcount=2 (+1)
$c = $b; // $a, $b, $c point to zval(new B) with refcount=3 (+1)
unset($a); // $b, $c point to zval(new B) with refcount=2 (-1)
一旦到达,就会释放并调用对象析构函数。refcount
0
zval
以下是一些达到范围的例子:refcount
0
-
unset
ing 一个变量:
$a = new B; // refcount=1
unset($a); // refcount=0 => __destruct!
但:
$a = new B; // refcount=1
$b = $a; // refcount=2
unset($a); // refcount=1 => no destruct as refcount > 0, even though unset() was called!
-
离开函数(或方法)范围
function a() {
$a = new B; // refcount=1
} // refcount=0 => __destruct! (as $a does not exist anymore)
-
脚本执行结束
$a = new B; // refcount=1
die(); // refcount=0 => __destruct! (on script execution end all vars are freed)
// doesn't need to be die(), can be just normal execution end
这些显然不是导致 减少 的所有条件,而是您最常遇到的条件。refcount
另外,我应该提到,由于PHP 5.3循环引用也会被检测到。因此,如果对象引用对象和引用,并且没有任何进一步的引用,或者两者的s将是,但它们仍然将被释放(和ed)。在这种情况下,破坏的顺序是未定义的行为。$a
$b
$b
$a
$a
$b
refcount
1
__destruct