class Foo {

    function Foo($name) {
        // 在全局数组 $globalref 中建立一个引用
        global $globalref;

        $globalref[] = &$this; //globalref[0] 放进一个对象
        // 将名字设定为传递的值

        $this->setName($name);
        // 并输出之
        $this->echoName();
    }    function echoName() {
        echo "<br />",$this->name;
//print_r($globalref);
    }    function setName($name) {
        $this->name = $name;
    }

}$bar1 = new Foo('set in constructor');
$bar1->setName('set from outside');$globalref[0]->echoName();$bar1->echoName();
你们觉得输出结果会是如何?理由呢?

解决方案 »

  1.   

    $bar1 = new Foo('set in constructor');  //会调用Foo()方法。
    因此$this->name='set in constructo',而$this->echoName();则会输出 <br />set in constructo$bar1->setName('set from outside'); //第二次为$name属性赋值,覆盖前者。
    因此输出两次  <br />set from outside 
      

  2.   

    <br />set in constructor
    <br />set from outside
    <br />set from outside有什么问题吗?
      

  3.   


    这里只改了 $bar1->setName('set from outside');
    globalref[0] 为什么会被改变啊?
      

  4.   

    PHP 手册里说:构造函数中的引用
    在构造函数中创建引用可能会导致混淆的结果。本节以教程形式帮助避免问题。 
    <?php
    class Foo {
        function Foo($name) {
            // 在全局数组 $globalref 中建立一个引用
            global $globalref;
            $globalref[] = &$this;
            // 将名字设定为传递的值
            $this->setName($name);
            // 并输出之
            $this->echoName();
        }    function echoName() {
            echo "<br />",$this->name;
        }    function setName($name) {
            $this->name = $name;
        }
    }
    ?>  下面来检查一下用拷贝运算符 = 创建的 $bar1 和用引用运算符 =& 创建的 $bar2 有没有区别... 
    <?php
    $bar1 = new Foo('set in constructor');
    $bar1->echoName();
    $globalref[0]->echoName();/* 输出:
    set in constructor
    set in constructor
    set in constructor */$bar2 =& new Foo('set in constructor');
    $bar2->echoName();
    $globalref[1]->echoName();/* 输出:
    set in constructor
    set in constructor
    set in constructor */
    ?>  显然没有区别,但实际上有一个非常重要的区别:$bar1 和 $globalref[0] 并没有被引用,它们不是同一个变量。这是因为“new”默认并不返回引用,而返回一个拷贝。 
      

  5.   

    要证明以上写的,看看下面的代码。 <?php
    // 现在改个名字,你预期什么结果?
    // 你可能预期 $bar1 和 $globalref[0] 二者的名字都改了...
    $bar1->setName('set from outside');// 但如同前面说的,并不是这样。
    $bar1->echoName();
    $globalref[0]->echoName();/* 输出为:
    set from outside
    set in constructor */// 现在看看 $bar2 和 $globalref[1] 有没有区别
    $bar2->setName('set from outside');// 幸运的是它们不但相同,根本就是同一个变量。
    // 因此 $bar2->name 和 $globalref[1]->name 也是同一个变量。
    $bar2->echoName();
    $globalref[1]->echoName();/* 输出为:
    set from outside
    set from outside */
    ?>  
      

  6.   

    类对象本来就是引用,不需要&
      

  7.   


    谁说的?用&是引用,否则是一份拷贝
      

  8.   

    上次回复里就告诉你,你在看的是手册里php4部分的内容.是已经过时的. 
    出现和运行不符合的结果没什么奇怪的.新的php5的oo的内容请看
    http://www.php.net/manual/zh/language.oop5.php如果这里你发现在php5.4内运行和结果不符的代码,
    请在这里贴出来或者直接报告到bugs.php.net谢谢
      

  9.   

    php5里,如果你打开错误显示$bar2 =& new Foo('set in constructor');这句你会看到一个警告信息.
      

  10.   

    楼上你看下这个例子:<?php
    class SimpleClass
    {
        // 成员声明
        public $var = 'a default value<br>';    // 方法声明
        public function displayVar() {
            echo $this->var;
        }
    }
    $instance = new SimpleClass();$assigned   =  $instance; //副本拷贝给 $assigned;$reference  =& $instance;// reference 直接引用到 $instance$instance->var = '$assigned will have this value';$instance = null; // $instance and $reference become nullvar_dump($instance);
    var_dump($reference);
    var_dump($assigned);?> 这里 $instance  和 $reference 不就是都指向同一个对象的引用吗?而$assigned  不是只获得了一份拷贝吗?否则 $instance = null; 之后,为什么 $assigned 却没受到影响呢?
      

  11.   

    我来试试能不能说清楚$instance = new SimpleClass();
    $assigned = $instance;
    $reference =& $instance;$instance->var = '$assigned will have this value';var_dump($instance);
    var_dump($reference);
    var_dump($assigned);得到
    object(SimpleClass)#1 (1) {
      ["var"]=>
      string(30) "$assigned will have this value"
    }
    object(SimpleClass)#1 (1) {
      ["var"]=>
      string(30) "$assigned will have this value"
    }
    object(SimpleClass)#1 (1) {
      ["var"]=>
      string(30) "$assigned will have this value"
    }
    三个都一样,说明
    $assigned = $instance; 
    是传递引用到 $assigned ,而不是将副本拷贝给 $assigned
    否则 $assigned 不会跟随变化$instance = new SimpleClass();
    是 $instance 对 new SimpleClass() 后的实体的引用$reference =& $instance;
    是变量间的引用
    所以一个变了,另一个也变了$assigned = $instance;
    实际上是赋值,只不过值是一个引用
      

  12.   

    "$assigned = $instance;
    实际上是赋值,只不过值是一个引用"你意思是说 $assigned 引用的是 $instance 的值,而不是 $instance 这个对象本身?所以 $assigned 在 $instance=null 之后,仍然有值?
      

  13.   

    你上面这个例子, instance和assigned都一样,都是该对象的引用.
    而reference是instance的引用, 间接指向了该对象
    就是 
    instance---->&object
    assigned---->&object
    reference--->&instance-->&object而$instance=null后,
    instance--->null
    assigned---->&object  不变
    reference--->&instance-->null所以assigned还是一样,没有变化
    这时object还在,不会被销毁
    如果assigned也=null了,该对象因为没有变量引用它,将会被垃圾收集.注意,这里$assigned=$instance不会创建一个新的object,
    所以如果需要复制一个新对象,我们需要clone,请看我上面给你的手册oo部分希望我已经讲清楚了...
      

  14.   

    嗯,这里我楼上说的不对
    看这里吧
    http://topic.csdn.net/u/20120430/17/f917e5b3-8447-42fa-8cbd-6d5a410cbedb.html