Я изучаю PHP-классы и исключения, и, исходя из фона С++, следующее выглядит как нечетное:
Когда конструктор производного класса выдает исключение, оказывается, что деструктор базового класса не запускается автоматически:
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.
С другой стороны, деструкторы объектов-членов выполняются должным образом, если в конструкторе есть исключение (at #1
). Теперь я задаюсь вопросом: как реализовать правильную разметку области в иерархии классов в PHP, чтобы подобъекты были надлежащим образом уничтожены в случае исключения?
Кроме того, кажется, что нет возможности запустить базовый деструктор после уничтожения всех объектов-членов (в #2
). Если мы удалим строку #1
, получим:
Base const.
Foo const.
Der const.
Der destr.
Base destr.
Foo destr. // ouch!!
Как решить эту проблему?
Обновление: Я по-прежнему открыт для дальнейших вкладов. Если у кого-то есть хорошее оправдание, почему объектная система PHP никогда не требует правильной последовательности уничтожения, я дам ей еще одну награду (или только за любой другой убедительно аргументированный ответ).