gpt4 book ai didi

php - 什么决定了类对象在 PHP 中何时被销毁?

转载 作者:IT王子 更新时间:2023-10-29 00:20:05 26 4
gpt4 key购买 nike

假设我们有类 CFoo。在以下示例中,何时调用 CFoo::__destruct()

function MyPHPFunc()
{
$foo = new CFoo();

. . .

// When/where/how does $foo get destroyed/deleted?
}

在这个例子中,当脚本退出 MyPHPFunc 的范围时是否会调用析构函数,因为 $foo 将不再可访问?

最佳答案

在 PHP 中,所有值都保存在所谓的 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 的一些示例:

  • 取消设置一个变量:

    $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 循环引用也会被检测到。因此,如果对象 $a 引用对象 $b 并且 $b 引用 $a 并且没有任何进一步的对 $a$b 的引用,两者的 refcount 都将为 1,但它们仍将被释放(和 __destructed)。在这种情况下,尽管销毁顺序是未定义的行为。

关于php - 什么决定了类对象在 PHP 中何时被销毁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8523433/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com