andre           Fri Mar  9 13:45:33 2001 EDT

  Modified files:              
    /phpdoc/en/language oop.xml 
  Log:
  Adding documentation for references inside the constructor
  
Index: phpdoc/en/language/oop.xml
diff -u phpdoc/en/language/oop.xml:1.7 phpdoc/en/language/oop.xml:1.8
--- phpdoc/en/language/oop.xml:1.7      Thu Feb 22 16:43:23 2001
+++ phpdoc/en/language/oop.xml  Fri Mar  9 13:45:32 2001
@@ -30,7 +30,7 @@
         }   
     }
 }
-?>
+?>
      </programlisting>
     </informalexample>
    </para>
@@ -195,6 +195,176 @@
     </simpara> 
    </caution>
   </sect1>
+  
+ <sect1 id="keyword.newref">
+   <title>references inside the constructor</title>
+   <para>
+    Creating references within the constructor can lead to confusing results. This 
+tutorial like section helps you
+    to avoid problems.
+ 
+    <informalexample>
+     <programlisting role="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;
+    }
+}
+    </programlisting>
+   </informalexample>
+
+   <para>
+   Let us check out if there is a difference between <varname>$bar1</varname> which 
+has been created using the copy <literal>=</literal> operator
+   and <varname>$bar2</varname> which has been created using the reference 
+<literal>=&</literal> operator...
+   </para>
+
+    <informalexample>
+     <programlisting role="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 */
+    
+        </programlisting>
+   </informalexample>
+   
+   <para>
+    Apparently there is no difference, but in fact there is a very significant one:
+    <varname>$bar1</varname> and <varname>$globalref[0]</varname> 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>
+         <simpara>
+         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).
+         </simpara>
+        </note>
+    To prove what is written above let us watch the code below.
+   </para>
+
+   <informalexample>
+     <programlisting role="php">
+        // now we will change the name. what do you expect?
+        // you could expect that both $bar 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 on object creation
+        set from outside */
+
+        // let us see what is different with $bar2 and $globalref[1]
+        $bar2->setName('set from outside');
+
+        // luckily they are not only equyl, they are thesame variable
+        // thus $bar2->Name and $globalref[1]->Name are the same too
+        $bar2->echoName();
+        $globalref[1]->echoName();
+
+        /* output:
+        set from outside
+        set from outside */
+        
+      </programlisting>
+   </informalexample>   
+   
+   <para>
+   Another final example, try to understand it.
+   
+   <informalexample>
+     <programlisting role="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 undestand 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
+*/
+      </programlisting>
+   </informalexample>   
+</para>
+</sect1>
+
  
  </chapter>
  


Reply via email to