6.4. Конструкторы и деструкторы
При объявлении в пределах класса с ключевым словом __construct функция будет считаться конструктором и выполняться непосредственно после создания объекта этого класса. Для того чтобы это было ясно, первые два символа являются символами подчеркивания. В отличие от других функций, конструктор может иметь параметры и даже значения, заданные по умолчанию. Существует возможность задавать классы, которые позволяют создавать объект, и его свойства в одном операторе. Кроме того, существует возможность задания метода __destruct. PHP вызывает этот метод при удалении объекта. Этот метод называется деструктором.
Одной из самых сильных сторон классов является механизм наследования, заключающийся в том, что один класс может распространить свою функциональность на другой класс. Новый класс будет содержать все методы и свойства наследуемого класса плюс свои собственные, объявленные непосредственно в нем. Кроме того, можно перекрывать методы и классы наследуемого класса. Как видно на рис. 6.1, класс наследует свойства с помощью ключевого слова extends.
Одним из самых интересных моментов можно назвать работу механизма наследования конструкторов. Несмотря на то что они наследуются так же, как и другие методы, они не могут вызываться, если из этого класса был создан объект. Если же все-таки вам необходима такая функциональность, ее следует задавать явным образом с помощью вызова конструктора родительского класса из конструктора порожденного класса. Вспомним в этой связи оператор :: (см. главу 2, "Переменные, операторы и выражения"), который позволяет обращаться к пространствам имен. Специальное пространство имен parent ссылается на непосредственного родителя. Порождающий конструктор можно вызвать с помощью parent::__construct.
В некоторых объектно-ориентированных языках программирования конструкторы указываются после класса. В предыдущих версиях PHP этот метод использовался и пока еще поддерживается. Это значит, что при вызове класса Animal и размещении метода внутри Animal PHP будет использовать его в качестве конструктора. Если в классе одновременно присутствует как __construct, так и метод, названный по
классу, PHP будет использовать_construct. Это позволит классам, написанным для
предыдущих версий, работать, как было задумано. Любой новый сценарий должен использовать_construct.
Новое соглашение по присвоению имен конструкторам, принятое для PHP, преду­сматривает возможность делать ссылку на конструкторы с унифицированным именем, независимо от имени класса, их содержащего. Это позволяет вносить изменения в иерархию классов, не прибегая к реальному изменению кода в самом классе.
Подобно другим методам, конструкторам в PHP можно присваивать тип доступа, который влияет на возможность создания экземпляров в определенных диапазонах. Таким образом, становится возможной реализация таких типовых проектов, каковым является, например, проект Синглетона.
Деструкторы, как это видно по их названию, по своему назначению и действию прямо противоположны конструкторам. Процессор PHP вызывает их при каждом удалении объекта из памяти. По умолчанию PHP удаляет из памяти свойства объекта и уничтожает все ресурсы, на которые ссылаются объекты. Деструкторы позволяют выполнять произвольный код для соответствующей очистки после объекта.
Деструкторы вызываются в тот момент, когда PHP определяет, что сценарий больше не ссылается на данный объект. В пределах пространства имен функции это происходит, как только функция возвращает управление. Для глобальных переменных это обычно происходит при остановке сценария. По необходимости уничтожить объект явным образом переменной, указывающей на этот объект, можно присвоить произвольное значение. Обычно в этих целях применяется операция присвоения переменной значения NULL или вызов функции unset. Класс, представленный в листинге 6.3, осуществляет подсчет объектов, экземпляры которых были запущены из него. Счетчик классов инкрементируется и декрементируется в самом конструкторе.
После объявления класса для создания экземпляра класса или объекта используется оператор new. Если определение класса можно назвать проектом, то по аналогии экземпляр можно назвать заготовкой, сошедшей с конвейера. Оператор new ожидает имя класса и возвращает новый экземпляр этого класса. При объявлении конструктора с параметрами имя класса можно сопровождать параметрами, заданными в скобках. Посмотрите на строки листинга 6.3, в которых используется оператор new.

Листинг 6.3. Конструкторы и деструкторы

<?php
class Counter
{
private static $count = 0; function __construct()
self::$count++; function __destruct()
self::$count-- ; function getCount()
return self::$count;
}}
// создать один экземпляр $c = new Counter(); // распечатать 1
print($c->getCount() . "<br>n"); // создать второй экземпляр $c2 = new Counter(); // распечатать 2
print($c->getCount() . "<br>n"); // уничтожить один экземпляр
$c2 = NULL;
// распечатать 1
print($c->getCount() . "<br>n");
?>

При создании экземпляра для всех его свойств резервируется память. Каждый экземпляр имеет свой собственный набор свойств, однако методы разделяются между экземплярами этого класса.