В штатном режиме, если всегда помнить о том, что в php5 присваивание происходит по ссылке, то нет никаких проблем, пока не используешь знак &.
http://www.php.net/manual/en/language.oop5.basic.php
<?php class SimpleClass{} class SimpleClass { // property declaration public $var = 'a default value'; // method declaration public function displayVar() { echo $this->var; } } ?>
Но подлинный смысл раскрывается этим комментарием:
http://www.php.net/manual/en/language.oop5.basic.php#79856
Я позволил себе его вольно перевести:
В php необходимо думать о переменных как о ячейках памяти. У каждой переменной если имя, которое ссылается на ячейку памяти(переменную), где хранится значение простого типа: число, строка, массив, и т.д. Когда вы создаете ссылку(&), вы создаете второе имя, которое ссылается на ту же саму ячейку памяти. Когда вы присваиваете одну переменную другой, вы копируете содержимое ячейки памяти в другую ячейку памяти.
Но присваивание экземпляров классов(далее объект) происходит не так как присваивание простых типов. Объекты не хранятся в ячейках памяти, которые программист "видит" на прямую. Вместо этого в ячейке памяти хранится указатель на объект. Таким образом указатель ведет себя как примитивный тип.
Когда вы присваиваете значение ссылки объекта одной переменной другой, обе переменные могут менять состояние одного и того же объекта. Но переменные не являются ссылками на объект, т.к. если присвоить одной из переменных новое значение, то это не отразится на другой переменной.
<?php // Assignment of an object Class Object{ public $foo="bar"; }; $objectVar = new Object(); $reference =& $objectVar; $assignment = $objectVar // // $objectVar --->+-----------+ // |(указатель1)----+ // $reference --->+-----------+ | // | // +-----------+ | // $assignment -->|(указатель2)----+ // +-----------+ | // | // v // Object(1):foo="bar" // ?>Значение переменной $assignment отличается от $objectVar, но эти значение ссылаются на один и тот же объект. Это поведение делает похожим на механизм передачи по ссылке. Если вы используете переменную $objectVar, чтобы поменять состояние объекта, то эти же изменения появятся и в переменной $assignment, т.к. они указывают на один и тот же объект.
<?php $objectVar->foo = "qux"; print_r( $objectVar ); print_r( $reference ); print_r( $assignment ); // // $objectVar --->+-----------+ // |(указатель1)----+ // $reference --->+-----------+ | // | // +-----------+ | // $assignment -->|(указатель2)----+ // +-----------+ | // | // v // Object(1):foo="qux" // ?>
Но с передачей значения по ссылке (&) дело обстоит совсем иначе. Если вы обнулите $objectVar, вы замените значение указателя в ячейке памяти на NULL. Это означает, что $reference, которая ссылается на туже ячейку памяти, также будет NULL. Но $assignment, которая ссылается на другую ячейку памяти, будет так же хранить копию указателя на объект, и она не будет равна NULL.
<?php $objectVar = null; print_r($objectVar); print_r($reference); print_r($assignment); // // $objectVar --->+-----------+ // | NULL | // $reference --->+-----------+ // // +-----------+ // $assignment -->|(указатель2)----+ // +-----------+ | // | // v // Object(1):foo="qux" ?>
К примеру, если взять java, где все переменные если ссылки на объекты, тот же пример выполняется так как и в php5 без символа &:
import java.util.*; class ObjectReference { public static void main(String[] args) { class Obj { int var = 1; } Obj objectVar = new Obj(); Obj reference = objectVar; objectVar.var = 2; System.out.println("objectVar.var="+objectVar.var); System.out.println("reference.var="+reference.var); objectVar = null; if (reference == null) { System.out.println("reference is null"); } else { System.out.println("reference is not null"); } } }ответ:
objectVar.var=2 reference.var=2 reference is not null