PHP 管理对象的方式与管理其他数据类型的方式不同。字符串(或整数、布尔值、浮点数或数组)直接存储在变量中。当变量的值被赋值给另一个变量时,该值被复制1到新变量中。
例如:
$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
// )
PHP如何处理对象分配?
另一方面,对象由 PHP 使用唯一标识符处理。将对象分配给变量时,标识符存储在变量中,而不是实际对象中。
当变量的值分配给另一个变量时,复制的是标识符而不是对象本身。这使得两个变量指向同一个对象。
使用您的示例,变量的值$instance
和$assigned
相等,它们都包含同一对象的标识符。$reference
另一方面,是一个引用,即变量的别名(不同的名称)$assigned
。这就是为什么该语句会$instance = null;
清除变量的内容,$reference
但$assigned
它不会影响变量$instance
以及标识符存储在其中的对象。
在设置$reference
为之前,null
可以使用或中的任何一个来访问在示例的第一行创建的对象。铁:$instance
$assigned
reference
SimpleClass
$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
在文档中阅读有关PHP 对象和引用的更多信息。
什么时候发生$assigned = clone $instance
?
clone
运算符创建其 操作数的副本。它创建一个新对象,并通过将原始对象的属性值分配给它们来初始化其所有属性。这意味着如果克隆对象包含对象作为属性,则这些属性通过简单赋值而不是通过克隆来复制。2
$assigned = clone $instance;
在此语句之后,$assigned
包含不同的值,$instance
因为它们现在存储不同对象的 ID。作为不同的对象, 的变化$instance
不再影响$assigned
。
$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这并不完全正确。出于优化目的,数组在被修改之前不会被复制(写时复制)。然而,这是一个实现细节,为了讨论的目的,考虑除对象之外的所有值在分配给新变量时都被复制。
2这也称为“浅层”克隆。为了获得“深度”克隆(与原始对象不共享任何内容的真正副本),具有对象作为属性的克隆对象的类必须实现__clone()
魔术方法并克隆原始对象的属性。此外,这些属性的类必须实现__clone()
等等。