Php 为什么将此引用对象设置为NULL不会重置其所有副本?
当我们将NULL分配给$instance时,为什么$assigned没有变为NULL?当我们通过$instance->var更改$var的值时,$assigned将获得新的更新值Php 为什么将此引用对象设置为NULL不会重置其所有副本?,php,class,oop,Php,Class,Oop,当我们将NULL分配给$instance时,为什么$assigned没有变为NULL?当我们通过$instance->var更改$var的值时,$assigned将获得新的更新值 class SimpleClass { // property declaration public $var = 'a default value'; // method declaration public function displayVar() { echo
class SimpleClass
{
// property declaration
public $var = 'a default value';
// method declaration
public function displayVar() {
echo $this->var;
}
}
$instance = new SimpleClass();
$assigned = $instance;
$reference =& $instance;
$instance->var = '$assigned will have this value';
$instance = null; // $instance and $reference become null
var_dump($instance);
var_dump($reference);
var_dump($assigned);
输出:
NULL
NULL
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned will have this value"
}
我使用的是PHP5.5.9。我认为这是因为对象本身在为其标识符分配空值后仍然完好无损 当您设置对象的字段时(它位于对象的内存部分),但当您将其指针设置为另一个值时(它位于其他位置),因此对象本身仍然存在,并且可以被另一个标识符指针引用 这里有一个参考:基础 要了解发生了什么,您需要深入了解php的内部结构,并了解如何管理内存 在引擎盖下,值表示如下:
+--------------------+
| (type) {{ VALUE }} |
| refcount = a |
| isref = b |
+--------------------+
参考计数器a统计指向该值的变量数。isref标志显示值是通过值分配的,即$a=value还是通过引用分配的,即$a=&value
让我们假设以下情况:
+--------------------------+
$a ------------->| (int) 58 | $a = 58
| refcount = 1 ; isref = 0 |
+--------------------------+
如果将$a的值复制到$b中,PHP只会增加refcount以提高内存效率,即不存储两倍于相同值的值:
+--------------------------+
$a -------+----->| (int) 58 | $b = $a
| | refcount = 2 ; isref = 0 |
| +--------------------------+
|
|
$b -------+
如果将$b的值更改为其他值,将创建一个新值,并将refcount减至58:
+--------------------------+
$a ------------->| (int) 58 | $b = 'hello'
| refcount = 1 ; isref = 0 |
+--------------------------+
+--------------------------+
$a ------------->| (string) 'hello' |
| refcount = 1 ; isref = 0 |
+--------------------------+
对于引用,isref标志设置为true,并且更改会影响两个标识符:
+--------------------------+
$a -------+----->| (int) 58 | $b =& $a
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$b -------+
关于对象引用
在PHP中,对象是通过引用透明地传递的,这不完全是真的。名称标识符$a包含一个对象标识符,这是函数之间传递的内容。我将在下面用一个object类型的整数来说明这个标识符,我不知道它到底是如何在引擎盖下完成的,但解释是正确的-
不要混淆标识符,即变量名和对象标识符,即内存中对象的编号
+--------------------------+
$a ------------->| (object) 547654764237685 | $a = new FooBar();
| refcount = 1 ; isref = 0 |
+--------------------------+
在内存中的其他地方,PHP存储我们刚刚创建的带有标识符547654764237685的FooBar实例。当您使用值对象547654764237685时,PHP自动检索所述对象并允许您透明地使用它
发生了什么事?
让我们逐行检查您的代码
首先创建一个新的SimpleClass实例
+--------------------------+
$instance ------>| (object) 547654764237685 | $instance = new SimpleClass();
| refcount = 1 ; isref = 0 |
+--------------------------+
然后对$assigned进行赋值,即增加refcount:
第三行引用$reference到$instance。由于该值的refcount大于1,并且它还不是引用isref=0,因此PHP在内存中创建了一个新的类似值:
+--------------------------+
$instance ---+-->| (object) 547654764237685 | $reference =& $instance;
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$reference --+
+--------------------------+
$assigned ------>| (object) 547654764237685 |
| refcount = 1 ; isref = 0 |
+--------------------------+
三个标识符$instance、$assigned和$reference对同一个对象求值,因为对象标识符保持不变。尽管如此,我们现在在内存中有两个不同的值
这就是调用$instance->var='$assigned将具有此值的原因;影响$instance->var、$assigned->var和$reference->var
现在,当您将$instance设置为null时,由于$reference引用相同的值,这两个值都会受到影响:
+--------------------------+
$instance ---+-->| (NULL) | $instance = null;
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$reference --+
+--------------------------+
$assigned ------>| (object) 547654764237685 |
| refcount = 1 ; isref = 0 |
+--------------------------+
$assigned的对象引用不受影响,因为它是一个单独的值,因此$assigned仍然调用该对象。当我们将NULL赋值给$instance时,为什么$assigned没有变为NULL?因为它们是两个完全不同的变量,$assigned既不知道也不关心你对$instance做了什么。长期以来,你在这个网站上得到了一个最好的答案——是否愿意回复作者,或者至少接受作者?从你没有回复我,或者下面的优秀答案来看,我投了反对票。
+--------------------------+
$instance ---+-->| (object) 547654764237685 | $reference =& $instance;
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$reference --+
+--------------------------+
$assigned ------>| (object) 547654764237685 |
| refcount = 1 ; isref = 0 |
+--------------------------+
+--------------------------+
$instance ---+-->| (NULL) | $instance = null;
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$reference --+
+--------------------------+
$assigned ------>| (object) 547654764237685 |
| refcount = 1 ; isref = 0 |
+--------------------------+