【问题标题】:What makes __destruct called twice in such a simple PHP code?是什么让 __destruct 在如此简单的 PHP 代码中被调用了两次?
【发布时间】:2012-01-17 07:30:33
【问题描述】:
<?php

class A
{
    static private $_instance = null;

    static public function Init()
    {   
        self::$_instance = new A();
    }   

    function __construct()
    {   
        echo "__construct\n";
    }   

    function __destruct()
    {   
        var_dump(debug_backtrace());
        echo "__destruct\n";
    }   
}
$a = A::Init();

通常,我们应该得到以下输出:(是的。我在 PHP 5.2.10-2ubuntu6.10 和 PHP 5.3.1 的 2 个不同服务器上得到了这个结果)

__construct
array(1) {
  [0]=>
  array(5) {
    ["function"]=>
    string(10) "__destruct"
    ["class"]=>
    string(1) "A"
    ["object"]=>
    object(A)#1 (0) {
    }
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(0) {
    }
  }
}
__destruct

但是,在另一台装有 CentOS 5.7 和 PHP 5.2.17 的服务器上,我得到了这个:

    __construct
    array(2) {
      [0]=>
      array(7) {
        ["file"]=>
        string(10) "/tmp/1.php"
        ["line"]=>
        int(7)
        ["function"]=>
        string(10) "__destruct"
        ["class"]=>
        string(1) "A"
        ["object"]=>
        object(A)#1 (0) {
        }
        ["type"]=>
        string(2) "->"
        ["args"]=>
        array(0) {
        }
      }
      [1]=>
      array(6) {
        ["file"]=>
        string(10) "/tmp/1.php"
        ["line"]=>
        int(21)
        ["function"]=>
        string(4) "Init"
        ["class"]=>
        string(1) "A"
        ["type"]=>
        string(2) "::"
        ["args"]=>
        array(0) {
        }
      }
    __destruct
    array(1) {
      [0]=>
      array(5) {
        ["function"]=>
        string(10) "__destruct"
        ["class"]=>
        string(1) "A"
        ["object"]=>
        object(A)#2 (0) {
        }
        ["type"]=>
        string(2) "->"
        ["args"]=>
        array(0) {
        }
      }
    }
    __destruct

为什么函数__destruct在这里调用了两次?尤其是第一次。

我认为配置中可能有一些特别之处,有什么建议吗?

谢谢。

===================

PS:这个问题不是由“单例设计模式”引起的。以下代码出现了同样的问题:

<?php
class A
{
    function __construct()
    {   
        echo "__construct\n";
    }

    function __destruct()
    {
        var_dump(debug_backtrace());
        echo "__destruct\n";
    }
}
$a = new A(); 

【问题讨论】:

  • @vascowhite:我觉得这不是一个完全重复。只知道 PHP 的人可能无法理解 C++ 中的那个例子。虽然答案可能有些相似,但目标受众却大不相同。
  • 可能与垃圾收集器有关?
  • 仅供参考,Mac 上的 PHP 5.2.17 此代码仅触发 __destruct 一次。
  • Mac 上的 PHP 5.3.5 也可以正常工作。您确定所有服务器上的代码都相同吗?
  • @TimG 感谢您的测试和回复。如果您在 php.ini 中打开设置 zend.ze1_compatibility_mode = On,您可以在结果中找到两次 __destruct。这可能是一个错误,请看我的回答。

标签: php destructor


【解决方案1】:

终于找到原因了。

这可能是 PHP 5.2.x 中的一个错误:

如果

zend.ze1_compatibility_mode = On 

然后你可以在执行我在问题中提供的代码时看到“__destruct”两次

其他版本已报告此问题:https://bugs.php.net/bug.php?id=29756

在我的测试中不影响 PHP 5.3。 (PHP 5.3 移除了这个设置)

希望这个答案对以后的一些人有所帮助:)

【讨论】:

    猜你喜欢
    • 2015-03-12
    • 2013-11-20
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    相关资源
    最近更新 更多