В штатном режиме, если всегда помнить о том, что в 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