О конструкторах
Опять тревога и батальон уходит в бой…
Давайте разберёмся с, казалось бы, одним из фундаментальных понятий в ООП 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 — оператор, а операндом является класс и параметры для его конструктора. Следовательно, выполнение этого оператора происходит в два этапа:
- выделение памяти под объект и инициализация значений его полей по умолчанию;
- инициализация объекта при помощи конструктора (если таковой имеется).
В данном случае до второго шага мы не доходим, так как исключение вылетает до начала инициализации объекта (то есть между первым и вторым этапами), в момент подготовки параметров конструктора.
Далее мы видим, что деструктор вызывается до обработки исключения. Тоже правильно: на объект не осталось ссылок и он становится интересен сборщику мусора. Заметим: не каждый вызов деструктора предваряется вызовом конструктора.
Естественно, после вылетевшего эксепшна переменная $a остаётся равна NULL, так как до присваивания дело ещё не дошло.
