   #PHP Manual Classes and Objects The magic functions __sleep and
   __wakeup Comparing objects in PHP 4

                  PHP Manual
   Prev Chapter 13. Classes and Objects Next
   ______________________________________________________________________

References inside the constructor

   Creating references within the constructor can lead to confusing
   results. This tutorial-like section helps you to avoid problems.

   <?php
   class Foo
   {
       function Foo($name)
       {
           // create a reference inside the global array $globalref
           global $globalref;
           $globalref[] = &$this;
           // set name to passed value
           $this->setName($name);
           // and put it out
           $this->echoName();
       }
       function echoName()
       {
           echo "<br>",$this->name;
       }
       function setName($name)
       {
           $this->name = $name;
       }
   }
   ?>

   Let us check out if there is a difference between $bar1 which has been
   created using the copy = operator and $bar2 which has been created
   using the reference =& operator...

   <?php
   $bar1 = new Foo('set in constructor');
   $bar1->echoName();
   $globalref[0]->echoName();
   /* output:
   set in constructor
   set in constructor
   set in constructor */
   $bar2 =& new Foo('set in constructor');
   $bar2->echoName();
   $globalref[1]->echoName();
   /* output:
   set in constructor
   set in constructor
   set in constructor */
   ?>

   Apparently there is no difference, but in fact there is a very
   significant one: $bar1 and $globalref[0] are _NOT_ referenced, they
   are NOT the same variable. This is because "new" does not return a
   reference by default, instead it returns a copy.

     Note: There is no performance loss (since PHP 4 and up use
     reference counting) returning copies instead of references. On the
     contrary it is most often better to simply work with copies instead
     of references, because creating references takes some time where
     creating copies virtually takes no time (unless none of them is a
     large array or object and one of them gets changed and the other(s)
     one(s) subsequently, then it would be wise to use references to
     change them all concurrently).

   To prove what is written above let us watch the code below.

   <?php
   // now we will change the name. what do you expect?
   // you could expect that both $bar1 and $globalref[0] change their
   names...
   $bar1->setName('set from outside');
   // as mentioned before this is not the case.
   $bar1->echoName();
   $globalref[0]->echoName();
   /* output:
   set from outside
   set in constructor */
   // let us see what is different with $bar2 and $globalref[1]
   $bar2->setName('set from outside');
   // luckily they are not only equal, they are the same variable
   // thus $bar2->name and $globalref[1]->name are the same too
   $bar2->echoName();
   $globalref[1]->echoName();
   /* output:
   set from outside
   set from outside */
   ?>

   Another final example, try to understand it.

   <?php
   class A
   {
       function A($i)
       {
           $this->value = $i;
           // try to figure out why we do not need a reference here
           $this->b = new B($this);
       }
       function createRef()
       {
           $this->c = new B($this);
       }
       function echoValue()
       {
           echo "<br>","class ",get_class($this),': ',$this->value;
       }
   }
   class B
   {
       function B(&$a)
       {
           $this->a = &$a;
       }
       function echoValue()
       {
           echo "<br>","class ",get_class($this),': ',$this->a->value;
       }
   }
   // try to understand why using a simple copy here would yield
   // in an undesired result in the *-marked line
   $a =& new A(10);
   $a->createRef();
   $a->echoValue();
   $a->b->echoValue();
   $a->c->echoValue();
   $a->value = 11;
   $a->echoValue();
   $a->b->echoValue(); // *
   $a->c->echoValue();
   /*
   output:
   class A: 10
   class B: 10
   class B: 10
   class A: 11
   class B: 11
   class B: 11
   */
   ?>
   ______________________________________________________________________

   Prev                                     Home                       Next
   The magic functions __sleep and __wakeup  Up  Comparing objects in PHP 4
