PHP doesn't manage the objects the same way it manages the other data types. A string (or an integer, boolean, float or array) is directly stored in the variable. When the value of the variable is assigned to another variable, the value is copied1 into the new variable.
For example:
$x = array('a');
$y = $x;
// $x and $y are different and unrelated variables; they do not share anything
$y[] = 'b';
print_r($y);
// Array
// (
// [0] => a
// [1] => b
// )
print_r($x);
// Array
// (
// [0] => a
// )
How PHP handles the objects assignment?
The objects, on the other hand, are handled by PHP using unique identifiers. When an object is assigned to a variable, the identifier is stored in the variable and not the actual object.
When the value of the variable is assigned to another variable, the identifier is copied and not the object itself. This makes the two variables point to the same object.
Using your example, the values of variables $instance
and $assigned
are equal, they both contain the identifier of the same object. $reference
, on the other side, is a reference, i.e. an alias (a different name) of variable $assigned
. This is why the statement $instance = null;
clears the content of variables $reference
and $assigned
but it doesn't affect the variable $instance
and also the object whose identifier is stored in it.
Before setting $reference
to null
, one can use any of $instance
, $assigned
or reference
to access the SimpleClass
object created on the first line of your example. F.e:
$instance = new SimpleClass();
$assigned = $instance;
$instance->var = '$assigned will have this value';
echo($instance->var);
// It prints:
// $assigned will have this value
// $assigned is also modified because it is the same object
echo($assigned->var);
// It prints:
// $assigned will have this value
Read more about PHP objects and references in the documentation.
What happens when $assigned = clone $instance
?
The clone
operator creates a duplicate of its operand. It creates a new object and it initializes all its properties by assigning the values of the properties of the original object to them. This means that if the clone object contains objects as properties, these properties are duplicated by simple assignment, not by cloning.2
$assigned = clone $instance;
After this statement, $assigned
contains a different value than $instance
because they store now the IDs of different objects. Being different objects, the changes of $instance
do not affect $assigned
any more.
$instance = new SimpleClass();
$instance->var = '$instance has this value';
$assigned = clone $instance;
echo($assigned->var);
// It prints:
// $instance has this value
$assigned->var = '$assigned has a different value';
echo($assigned->var);
// It prints:
// $assigned has a different value
// $instance is not modified
echo($instance->var);
// It prints:
// $instance has this value
1 This is not entirely true. For optimization purposes, the arrays are not copied until they are modified (copy-on-write). However, this is an implementation detail and for the purpose of this discussion it is fine to consider all values except the objects are copied when they are assigned to a new variable.
2 This is also called "shallow" cloning. In order to get a "deep" clone (a real duplicate that doesn't share anything with the original), the class of a cloned object that has objects as properties must implement the __clone()
magic method and clone the properties of the original object. Also, the classes of these properties must implement __clone()
and so on.