通过引用分配,对象的值?

时间:2011-04-06 08:43:50

标签: php oop

我正在通过阅读php官方文档来学习OOP的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);

结果:

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

这个例子我不明白由reference and value

指定的

这里。但我看到了结果输出。但我还是没有想到。

我的问题是为什么$ instance和$ reference变为null?

3 个答案:

答案 0 :(得分:3)

  

我的问题是为什么$instance$reference变为空?

PHP引用以有趣的方式运行。我要打破现实生活中的类比。

想象一下,你有一个杯子。杯子里装满了水。

杯子是一个变量。水是变量的内容。

您创建的任何参考都指向杯子,而不是水。

如果用咖啡更换杯子中的水,那么所有对杯子的引用都会突然含有相同的咖啡。

当你把杯子倒空时,所有杯子的参考都突然变空了。

现在,对象非常有趣。您可以看到,当您将它们分配给变量时,实际上它通过引用实现了种类。但是对象不是正常引用。从PHP交互式提示符:

php > class Foo { public $bar; }
php > $f = new Foo();
php > $f->bar = 1;
php > $f_copy = $f;
php > $f_copy->bar = 2;
php > echo $f->bar;
2

不是你的预期,对吗?它变得更有趣。

php > $f_copy = $f;
php > $copy_ref = &$f_copy;
php > $copy_ref->bar = 3;
php > echo $f->bar;
3

这有点期待。但这是吗?

php > $f_copy = null;
php > print_r($copy_ref);
php > var_export($copy_ref);
NULL
php > print_r($f);
Foo Object
(
    [bar] => 3
)

正如您所看到的,即使我们完全清空了包含对象引用的变量,原始对象仍未被触及,即使该对象也通过引用放入副本中!

欢迎使用PHP,这样的事情是正常的。我建议经常检查你自己的理智。

编辑:哦,还有一件事。如果您需要制作对象的真实副本,则必须clone

php > $not_f = clone $f;
php > $not_f->bar = 'I am not $f';
php > echo $f->bar;
3
php > echo $not_f->bar;
I am not $f

它也适用于refs:

php > $not_f_copy = $not_f;
php > $not_copy_ref = &$not_f_copy;
php > $headsplode = clone $not_copy_ref;
php > $not_f->bar = 'No, I am Spartacus!';
php > echo $headsplode->bar;
I am not $f

哦,在有人问之前:在一些语言中,引用工作在值级别,而不是变量级别。 Perl就是一个很好的例子。如果创建对变量的引用,然后重新分配原始引用,则引用仍包含原始值。我通过Perl来到PHP,这看似微小的差异驱使我爬上墙。

答案 1 :(得分:2)

$instance$reference都指向相同的内存位置。

如果您愿意,$instance仅仅是给予该内存位置的名字$reference 是第二个名称。 “通过引用分配”的行为可以描述为“通过附加名称使存储器位置已知”。

如果您现在将该内存位置设置为NULL,则引用该内存位置的所有名称都将为空。

但是,$assigned是原始对象的(浅)副本。因此它位于不同的位置。这就是为什么它仍然具有$var值。

相关的PHP文档:

答案 2 :(得分:1)

变量的值是该变量的实际内容。例如,如果你有一个100个元素的字节数组,那么这个数组的值在内存中需要100个字节。

对变量的引用是不同的,它是该变量的内存地址。例如,在x86系统上,此引用应占用4个字节,而在64位系统上,则占用8个字节。

以上2点解决了常识性问题& OOP中的引用(指针); PHP可能会以另一种不同的方式保存

$ instance因为你将它设置为null而变为null,因此,对null的引用当然是null。

关于变量$ assigned,当php执行到这行代码时

$assigned = $instance;

php创建另一个对象并将$ instance中的值复制到$ assigned,这就是为什么当你第三次调用var_dump时,它会显示$ instance中的原始值,尽管$ instance已被设置为null,但是var_dump调用