Php 为什么指向同一对象的两个对象实例中的一个在为它们中的任何一个指定NULL时表现不同?

Php 为什么指向同一对象的两个对象实例中的一个在为它们中的任何一个指定NULL时表现不同?,php,class,object,reference,Php,Class,Object,Reference,考虑以下代码片段: <?php class SimpleClass { // property declaration public $var = 'a default value'; // method declaration public function displayVar() { echo $this->var; } } $instance = new SimpleClass(); $assigned

考虑以下代码片段:

<?php
  class SimpleClass {
    // property declaration
    public $var = 'a default value';

    // method declaration
    public function displayVar() {
      echo $this->var;
    }
  }

  $instance = new SimpleClass();

  $assigned   =  $instance;

  $instance->var = '$assigned will have this value';
  var_dump($instance);
  echo "<br>";
  var_dump($assigned);
?>
我很理解上面的程序。我知道,对
$instance
$assigned
的任何更改都将反映在另一个实例中,因为它们指向同一个对象实例

但是,当将
NULL
分配给两个对象实例中的任何一个时,此原则在下面的代码中失败。预期两个对象实例都应变为
NULL
,但其中一个包含
NULL
,另一个不包含
NULL
。为什么会这样

<?php
  class SimpleClass {
    // property declaration
    public $var = 'a default value';

    // method declaration
    public function displayVar() {
      echo $this->var;
    }
  }

  $instance = new SimpleClass();

  $assigned   =  $instance;

  $instance = NULL;
  var_dump($instance);
  echo "<br>";
  var_dump($assigned);
?>
此外,在上面的代码中,如果调用类方法
displayVar()
,该类方法回显文本
'a default value'
,或者没有任何构造函数方法,那么如何设置对象实例
$assigned
var
属性,而不是在其中设置
NULL


由于两个对象实例都指向同一个对象,因此当
NULL
被分配给其中一个对象和另一个对象(预期值)时,它们以一种方式运行字符串或某个有意义的值分配给其中一个变量时的方式?

$assigned=$instance
意味着您正在复制指针,因为每当您将新对象分配给变量时,基本上就是对该对象进行指针引用

因此,当您执行
$instance=NULL
操作时,您将为$instance变量赋值NULL,而
$assigned
仍然指向您先前创建的对象


看看这个链接

当你创建一个对象时,PHP会在引擎盖下创建一个zval。它是存储对象结构和数据的内存空间。好的,但这就是这个案子你需要知道的全部

将对象分配给
$instance
意味着将指针类的东西分配给这个zval。然后执行
$assigned=$instance
时,PHP也会使
$assigned
指向此zval:

$instance -> your object <- $assigned
    ^                           ^
    |____________ = ____________|
让我们在一个交互式会话中尝试一下(在shell中键入
php-a
):

这不同于使用实际引用,其中
$assigned
实际指向
$instance
的指针:

your object <- $instance <- $assigned
                   ^            ^
                   |_____= _____|
通过执行
$b=&$a
$b
并不直接指向zval,而是指向
$a
实际上,因此当您将
NULL
分配给
$a
时,
$b
将是您分配给
$a
的任何内容,反之亦然,例如,如果您随后执行
$b=42
,则
$a
也将是42:

$instance = null;
// causes
null <- $instance <- $assigned
            ^            ^
            |_____= _____|
$instance=null;
//原因

null查看第一个代码段。在其中,$assigned和$instance的属性值都发生了变化。因此,当NULL被分配给它们中的任何一个时,它们的行为应该是相同的。为什么不同类型的值在行为上存在如此大的差异?@user2839497在第一个代码段中,您正在更改对象本身,该对象由两个变量
$assigned
$instance
引用。但是,当您执行
$assigned=NULL
操作时,您并没有使对象变为NULL,而是使
$assigned
在对象本身仍然安全的情况下引用NULLmemory@user2839497没有区别。在这两种情况下,您分配的变量都会获取值。一个是
var
,另一个是
实例
。通过将对象分配给变量,它只复制该对象的“内存地址”,而不是整个对象及其内容。要复制对象及其内容,需要使用:$assigned=clone$instance;谢谢你完整而有意义的解释。最后一句话“$b将是您分配给$b的任何对象”,您的意思是在删除变量$a后,我可以为变量$b分配任何值,因为它在删除$a后变为自由/空/空(这是一个引用)?@user2839497抱歉,我输入错误。补充说明。抱歉再次打扰您。但这是我最后的怀疑。“删除$a”是指取消设置($a)还是$a=NULL或其他内容?@user再次更新。希望这能澄清这一点。我建议使用交互式控制台来处理它。您可以通过shell上的
php-a
启动它。@php在其中键入“exit”
$instance = NULL;

// causes

$instance -> NULL
     ^       your object <- $assigned
     |                          ^
     |___________ != ___________|
php > $a = new StdClass;
php > $a->foo = 42;
php > $b = $a;
php > var_dump($b);
object(stdClass)#1 (1) {
  ["foo"]=>
  int(42)
}
php > $a = null;
php > var_dump($b);
object(stdClass)#1 (1) {
  ["foo"]=>
  int(42)
}
your object <- $instance <- $assigned
                   ^            ^
                   |_____= _____|
php > $a = new StdClass;
php > $a->foo = 42;
php > $b = &$a;
php > var_dump($b);
object(stdClass)#2 (1) {
  ["foo"]=>
  int(42)
}
php > $a = null;
php > var_dump($b);
NULL
$instance = null;
// causes
null <- $instance <- $assigned
            ^            ^
            |_____= _____|