适用于PHP类构造函数的范围

前端之家收集整理的这篇文章主要介绍了适用于PHP类构造函数的范围前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在学习 @L_301_0@类和例外,而从C的背景来看,以下是我的奇怪:

当派生类的构造函数抛出异常时,看起来基类的析构函数不会自动运行:

class Base
{
  public function __construct() { print("Base const.\n"); }
  public function __destruct()  { print("Base destr.\n"); }
}

class Der extends Base
{
  public function __construct()
  {
    parent::__construct();
    $this->foo = new Foo;
    print("Der const.\n");
    throw new Exception("foo"); // #1
  }
  public function __destruct()  { print("Der destr.\n"); parent::__destruct(); }
  public $foo;                  // #2
}

class Foo
{
  public function __construct() { print("Foo const.\n"); }
  public function __destruct()  { print("Foo destr.\n"); }
}


try {
  $x = new Der;
} catch (Exception $e) {
}

打印:

Base const.
Foo const.
Der const.
Foo destr.

另一方面,如果构造函数中有异常(#1),则会正确执行成员对象的析构函数.现在我想知道:如何在PHP中的类层次结构中实现正确的范围展开,以使子对象在发生异常时被正确地销毁?

此外,在所有成员对象被销毁之后,似乎没有办法运行基础析构函数(在#2).如果我们删除第1行,我们得到:

Base const.
Foo const.
Der const.
Der destr.
Base destr.
Foo destr.    // ouch!!

如何解决这个问题?

更新:我仍然愿意做进一步的贡献.如果有人有一个很好的理由,为什么PHP对象系统从来不需要正确的销毁序列,我会给出另一个赏金(或者只是为了任何其他有说服力的争论答案).

我想解释为什么PHP这样做,为什么它实际上(某些)有意义.

PHP中,只要没有更多的引用,对象就被销毁.参考可以通过多种方式去除,例如通过取消设置()变量,通过保留范围或作为关闭的一部分.

如果你明白这一点,你可以很容易的理解这里发生了什么(我将首先解释没有Exception的情况):

> PHP进入关机,因此所有的变量引用被删除.
>当$x(对Der的实例)创建的引用被删除时,对象被销毁.
>派生析构函数调用,它调用基本析构函数.
>现在,从$this-> foo到Foo实例的引用被删除(作为摧毁成员字段的一部分).
>没有任何对Foo的引用,所以它也被破坏,析构函数调用.

想象一下,这不会以这种方式工作,成员字段将在调用析构函数之前被销毁:在析构函数中不能访问它们.我非常怀疑C中有这样的行为.

在异常情况下,您需要了解,对于PHP,从来没有真正存在类的实例,因为构造函数从未返回.你怎么能破坏从未构建过的东西?

如何解决

你没有您只需要一个析构函数的事实可能就是设计不好的一个迹象.而毁灭令对你来说很重要的事实更是如此.

猜你在找的PHP相关文章