О конструкторах

Опять тревога и батальон уходит в бой…

Давайте разберёмся с, казалось бы, одним из фундаментальных понятий в ООП PHP5, а именно с конструкторами и деструкторами, а то, как выяснилось, эта тема не совсем очевидна.

class Test {
    private $_arg = "no arg";
    function __construct($arg) {
        print "I'm constructor: $arg\n";
        $this->_arg = $arg;
    }
    function __destruct() {
        print "I'm destructor: $this->_arg\n";
    }
}
function iLoveExceptions() {
    throw new Exception("Ha ha!");
}
try {
    $a = new Test(iLoveExceptions());
}
catch(Exception $e) {
    print "Exception!!\n";
}

В итоге мы получаем следующий вывод:

I'm destructor: no arg
Exception!!

Почему так происходит?

Начнём с того, что new — оператор, а операндом является класс и параметры для его конструктора. Следовательно, выполнение этого оператора происходит в два этапа:

  1. выделение памяти под объект и инициализация значений его полей по умолчанию;
  2. инициализация объекта при помощи конструктора (если таковой имеется).

В данном случае до второго шага мы не доходим, так как исключение вылетает до начала инициализации объекта (то есть между первым и вторым этапами), в момент подготовки параметров конструктора.
Далее мы видим, что деструктор вызывается до обработки исключения. Тоже правильно: на объект не осталось ссылок и он становится интересен сборщику мусора. Заметим: не каждый вызов деструктора предваряется вызовом конструктора.

Естественно, после вылетевшего эксепшна переменная $a остаётся равна NULL, так как до присваивания дело ещё не дошло.

Posted on May 27, 2009 at 7:47 PM by Dinexi · Permalink
In: главная · Tagged with: ,

Leave a Reply