在修改已在以下代码中创建了引用的对象时实际修改了什么?

PHP*_*Fan 0 php reference class object

我正在使用PHP 7.1.11

考虑以下代码:

<?php
  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);
?>
Run Code Online (Sandbox Code Playgroud)

以上程序的输出如下:

NULL
NULL
object(SimpleClass)#1 (1) {
   ["var"]=>
     string(30) "$assigned will have this value"
}
Run Code Online (Sandbox Code Playgroud)

如果查看代码行,$reference =& $instance;您会注意到& instance创建了对现有类对象()的引用并将其分配给变量$reference.

然后我的问题与以下代码行有关:

$instance->var = '$assigned will have this value';

$instance = null; // $instance and $reference become null
Run Code Online (Sandbox Code Playgroud)

这些语句实际上是修改原始对象或对象引用中的数据?

我预计语句的输出var_dump($assigned);作为NULL,但事实并非如此.为什么这样?这背后的原因是什么?PHP程序流如何在这里工作?

为什么在执行语句时$instance = null;变量$assigned没有被分配给值NULL

Don*_*nic 5

要实现的重要一点是,不同的变量包含对象标识符,而不是对象本身.从对象和引用的PHP文档:

PHP引用是一个别名,它允许两个不同的变量写入相同的值.从PHP 5开始,对象变量不再包含对象本身作为值.它只包含一个对象标识符,允许对象访问者查找实际对象.当一个对象通过参数发送,返回或分配给另一个变量时,不同的变量不是别名:它们包含标识符的副本,该副本指向同一个对象.

所以,一步一步:

  1. 首先创建对象,并将对象标识符分配给$instance.

    $instance = new SimpleClass();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 指定了对象标识符的副本$assigned.

    $assigned = $instance;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 指定对象标识符的引用$reference.

    $reference  =& $instance;
    
    Run Code Online (Sandbox Code Playgroud)
  4. 显然,这会修改var所有不同变量引用的对象的属性.

    $instance->var = '$assigned will have this value';
    
    Run Code Online (Sandbox Code Playgroud)
  5. 此语句替换对象标识符$instancenull,并通过引用,它也取代了$reference.

    $instance = null; // $instance and $reference become null
    
    Run Code Online (Sandbox Code Playgroud)

但是在设置$instance为null之后,对象本身仍然存在,并且$assigned仍然保存其标识符的副本.


这是一个MSPaint视觉辅助以防万一,因为我被告知我可能有些迟钝.(我遗漏了第4步.)

在此输入图像描述

  • 我不认为我说的恰恰相反.手册指出新变量将访问同一个实例,并且`$ assigned`和`$ instance` _do_访问完全相同的类实例; 他们只是通过不同的标识符访问它.我认为手册只是强调在分配给新变量时不复制实例. (3认同)