Developers/Object oriented programming in PHP/Objects/ru

Хранение объектов в PHP
Для хранения объектов PHP использует таблицы хешей. Они структурированы в виде пар ключ/значение, то есть определённому ключу в столбце key отвечают данные объекта в столбце value.

При создании нового объекта и связывания его с переменной, вроде, происходит следующее: выделяется память для объекта, вызывается метод конструктор для инициализации объекта, и идентификатор для этого объекта сохраняется в хеш таблице, которая управляет объектами и ссылками блока памяти. Этот идентификатор назначается в виде значения на переменную $objBar, таким образом $objBar содержит лишь ссылку на объект, на не фактические данные объекта.

Назначение и копирование объектов
Далее, если эту переменную $objBar назначить на другую переменную $objFoo таким образом

то применимы обычные правила для назначения в PHP: содержимое $objBar копируется и назначается на $objFoo. Но содержимое $objBar — простой идентификатор объекта, поэтому этот идентификатор и копируется. Следовательно, обе переменные, $objBar и $objFoo</tt> теперь указывают на тот же идентичный объект. Другими словами, объект доступен и через $objBar</tt>, и через $objFoo</tt>. Создаётся так называемый общий ресурс, а объект не копируется.

Ввиду этого, остаётся возможность изменить внутреннее состояние объекта посредством вызова его публичных/public методов, даже после того, как ссылка на объект была уже передана другому объекту. Это может быть очень эффективным, но и очень опасным, поэтому такая обработка должна производится осторожно, так как могут возникнуть трудноуловимые ошибки. Для фактического копирования объекта с теми же значениями свойств должно использоваться ключевое слово clone</tt>:

При помощи clone</tt> все свойства клонируемого объекта копируются в новый объект. Свойства, содержащие скалярные типы или массивы просто копируются при назначении, но, если свойства клонируемого объекта сами содержат идентификаторы объектов, то копируются лишь эти идентификаторы. В результате получим два разных объекта, свойства которых указывают на одни и те же объекты. Чтобы обойти это и фактически скопировать объекты, связанные со свойствами клонируемого объекта, в определении класса клонируемого объекта должен быть реализован волшебный метод __clone</tt>. В этом методе __clone</tt> при помощи всё того же ключевого слова clone</tt> могут быть клонированы объекты, на которые ссылаются его свойства:

Проблемы использования деструкторов
Деструкторы могут быть реализованы для чистки перед фактическим удалением объекта, что происходит по окончании работы сценария или при работе по сборке мусора более не существует переменная, указывающая на объект. Если имеется метод __destruct</tt>, то он исполняется, даже если сценарий уничтожается при помощи.

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

Ещё одна проблема возникает при попытке доступа к глобальным ресурсам не эксклюзивно управляемым сами объектом в деструкторе. Высок шанс, что глобальные ресурсы уже удалены при вызове деструктора объекта, что выливается в fatal error при попытке вызова методов несуществующего объекта.

Смотрите также

 * http://php.net/manual/en/language.oop5.references.php
 * http://php.net/manual/en/language.oop5.cloning.php
 * http://php.net/manual/en/language.oop5.decon.php

<< Назад: методы | Далее: абстрактные классы и интерфейсы >>