tom             Wed Mar 27 14:22:06 2002 EDT

  Modified files:              
    /phpdoc/de/language oop.xml 
  Log:
  file is finally complete now, translation will follow soon
  
Index: phpdoc/de/language/oop.xml
diff -u phpdoc/de/language/oop.xml:1.7 phpdoc/de/language/oop.xml:1.8
--- phpdoc/de/language/oop.xml:1.7      Wed Dec 12 15:46:22 2001
+++ phpdoc/de/language/oop.xml  Wed Mar 27 14:22:06 2002
@@ -1,30 +1,35 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Revision: 1.8 $ -->
  <chapter id="language.oop">
-  <title>Klassen und Objekte</title>
+  <title>Classes and Objects</title>
 
   <sect1 id="keyword.class">
-   <title><literal>Klassen</literal></title>
+   <title><literal>class</literal></title>
    <para>
-    Eine Klasse ist eine Sammlung von Variablen und von Funktionen,
-    die mit diesen Variablen arbeiten. Eine Klasse wird folgendermaßen
-    definiert:
+    A class is a collection of variables and functions working with
+    these variables.  A class is defined using the following syntax:
+ 
     <informalexample>
      <programlisting role="php">
-&lt;?php
-class Einkaufswagen {
-    var $produkte;  // Produkte in Ihrem Einkaufswagen
+<![CDATA[
+<?php
+class Cart
+{
+    var $items;  // Items in our shopping cart
    
-    // Füge dem Einkaufswagen $anzahl Artikel der Sorte $artnr zu
+    // Add $num articles of $artnr to the cart
  
-    function fuege_hinzu ($artnr, $anzahl) {
-        $this->produkte[$artnr] += $anzahl;
+    function add_item ($artnr, $num)
+    {
+        $this->items[$artnr] += $num;
     }
    
-    // Nimm $anzahl von Artikel wieder aus dem Einkaufswagen
+    // Take $num articles of $artnr out of the cart
  
-    function nimm_heraus ($artnr, $anzahl) {
-        if ($this->produkte[$artnr] > $anzahl) {
-            $this->produkte[$artnr] -= $anzahl;
+    function remove_item ($artnr, $num)
+    {
+        if ($this->items[$artnr] > $num) {
+            $this->items[$artnr] -= $num;
             return true;
         } else {
             return false;
@@ -32,122 +37,870 @@
     }
 }
 ?>
+]]>
      </programlisting>
     </informalexample>
    </para>
+ 
+   <para>
+    This defines a class named Cart that consists of an associative
+    array of articles in the cart and two functions to add and remove
+    items from this cart.
+   </para>
+
+   <caution>
+    <simpara>
+     The following cautionary notes are valid for PHP 4.
+    </simpara>
+    
+    <simpara>
+     The name <literal>stdClass</literal> is used interally by
+     Zend and is reserved. You cannot have a class named
+     <literal>stdClass</literal> in PHP.
+    </simpara>
+    
+    <simpara>
+      The function names <literal>__sleep</literal> and
+      <literal>__wakeup</literal> are magical in PHP classes. You
+      cannot have functions with these names in any of your
+      classes unless you want the magic functionality associated
+      with them. See below for more information.
+    </simpara>
+    
+    <simpara>
+      PHP reserves all function names starting with __ as magical.
+      It is recommended that you do not use function names with
+      __ in PHP unless you want some documented magic functionality.
+    </simpara>
+   </caution>
+
+   <note>
+    <simpara>
+     In PHP 4, only constant initializers for <literal>var</literal>
+     variables are allowed. To initialize variables with non-constant
+     values, you need an initialization function which is called
+     automatically when an object is being constructed from the
+     class. Such a function is called a constructor (see below).
+    </simpara>
+    <informalexample>
+     <programlisting role="php">
+<![CDATA[
+<?php
+/* None of these will work in PHP 4. */
+class Cart
+{
+    var $todays_date = date("Y-m-d");
+    var $name = $firstname;
+    var $owner = 'Fred ' . 'Jones';
+    var $items = array("VCR", "TV");
+}
+
+/* This is how it should be done. */
+class Cart
+{
+    var $todays_date;
+    var $name;
+    var $owner;
+    var $items;
+
+    function Cart()
+    {
+        $this->todays_date = date("Y-m-d");
+        $this->name = $GLOBALS['firstname'];
+        /* etc. . . */
+    }
+}
+]]>
+     </programlisting>
+    </informalexample>
+   </note>
+
+   <para>
+    Classes are types, that is, they are blueprints for actual
+    variables. You have to create a variable of the desired type with
+    the <literal>new</literal> operator.
+   </para>
+ 
+   <informalexample>
+    <programlisting role="php">
+<![CDATA[
+<?php
+$cart = new Cart;
+$cart->add_item("10", 1);
+
+$another_cart = new Cart;
+$another_cart->add_item("0815", 3);
+]]>
+    </programlisting>
+   </informalexample>
+ 
    <para>
-    In diesem Beispiel wird eine Klasse "Einkaufswagen" definiert. Sie
-    besteht aus einem assoziativen Array von Produkten im
-    Einkaufswagen und zwei Funktionen zum Zufügen und Entfernen von
-    Einkäufen.
+    This creates the objects $cart and $another_cart, both of
+    the class Cart. The function add_item() of the $cart object
+    is being called to add 1 item of article number 10 to the
+    $cart. 3 items of article number 0815 are being added to
+    $another_cart.
    </para>
+   
    <para>
-    Klassen sind Typen, dass heisst die Blaupausen für realle
-    Variablen.  Um sie zu nutzen, muß zunächst eine Variable mit dem
-    Operator <literal>new</literal> angelegt werden.
+    Both, $cart and $another_cart, have functions add_item(),
+    remove_item() and a variable items. These are distinct
+    functions and variables. You can think of the objects as
+    something similar to directories in a filesystem. In a
+    filesystem you can have two different files README.TXT, as
+    long as they are in different directories.  Just like with
+    directories where you'll have to type the full pathname in
+    order to reach each file from the toplevel directory, you
+    have to specify the complete name of the function you want
+    to call: In PHP terms, the toplevel directory would be the
+    global namespace, and the pathname separator would be -&gt;. 
+    Thus, the names $cart-&gt;items and $another_cart-&gt;items
+    name two different variables. Note that the variable is
+    named $cart-&gt;items, not $cart-&gt;$items, that is, a
+    variable name in PHP has only a single dollar sign.
    </para>
+
    <informalexample>
     <programlisting role="php">
-$einkaufswagen = new Einkaufswagen;
-$einkaufswagen->fuege_hinzu("10", 1);
+<![CDATA[
+// correct, single $
+$cart->items = array("10" => 1); 
+
+// invalid, because $cart->$items becomes $cart->""
+$cart->$items = array("10" => 1);
+
+// correct, but may or may not be what was intended:
+// $cart->$myvar becomes $cart->items
+$myvar = 'items';
+$cart->$myvar = array("10" => 1);  
+]]>
     </programlisting>
    </informalexample>
+
    <para>
-    Hier wird das Objekt $einkaufswagen aus der Klasse Einkaufswagen
-    geschaffen. Dann wird die enthaltene Funktion fuege_hinzu()
-    aufgerufen, um ein Produkt mit der Artikelnummer 10 in den
-    Einkaufswagen zu tun.
+    Within a class definition, you do not know under which name the object will
+    be accessible in your program: at the time the Cart class was 
+    written, it was unknown that the object will be named $cart or
+    $another_cart later. Thus, you cannot write $cart-&gt;items within
+    the Cart class itself. Instead, in order to be able to access it's own
+    functions and variables from within a class, one can use the
+    pseudo-variable $this which can be read as 'my own' or
+    'current object'. Thus, '$this-&gt;items[$artnr] += $num' can
+    be read as 'add $num to the $artnr counter of my own items
+    array' or 'add $num to the $artnr counter of the items array
+    within the current object'.
    </para>
+  </sect1>
+  
+  <sect1 id="keyword.extends">
+   <title><literal>extends</literal></title>
+
    <para>
-    Klassen können ebenfalls Erweiterungen von anderen Klassen sein.
-    Die erweiterte, oder auch abgeleitete Klasse enthält alle
-    Funktionen der ursprünglichen Klasse, und dazu die eigenen
-    Ergänzungen.  Das geschieht mit dem Schlüsselwort
-    "extends". Mehrfachvererbung wird von PHP nicht unterstützt.
+    Often you need classes with similar variables and functions
+    to another existing class. In fact, it is good practice to
+    define a generic class which can be used in all your
+    projects and adapt this class for the needs of each of your
+    specific projects. To facilitate this, classes can be
+    extensions of other classes.  The extended or derived class
+    has all variables and functions of the base class (this is
+    called 'inheritance' despite the fact that nobody died) and what
+    you add in the extended definition. It is not possible to
+    substract from a class, that is, to undefine any existing 
+    functions or variables. An extended class is always dependent
+    on a single base class, that is, multiple inheritance is
+    not supported. Classes are extended using the keyword 'extends'.
    </para>
+ 
    <informalexample>
     <programlisting role="php">
-class Mein_Einkaufswagen extends Einkaufswagen {
-    var $besitzer;
+<![CDATA[
+class Named_Cart extends Cart
+{
+    var $owner;
   
-    function setze_besitzer ($name) {
-        $this->besitzer = $name;
+    function set_owner ($name)
+    {
+        $this->owner = $name;
     }
 }
+]]>
     </programlisting>
    </informalexample>
+ 
    <para>
-    In diesem Beispiel wird eine Klasse Mein_Einkaufswagen definiert.
-    Sie enthält alle Funktionen der Klasse Einkaufswagen, eine
-    zusätzliche Variable $besitzer und die zusätzliche Funktion
-    setze_besitzer().  Man kann den Einkaufswagen auch weiterhin wie
-    oben erzeugen, nur kann man jetzt auch den Besitzer setzen oder
-    herausfinden. Die alten Funktionen der Klasse Einkaufswagen können
-    ebenfalls weiterverwendet werden.
+    This defines a class Named_Cart that has all variables and
+    functions of Cart plus an additional variable $owner and an
+    additional function set_owner(). You create a named cart the usual
+    way and can now set and get the carts owner. You can still use
+    normal cart functions on named carts:
    </para>
+ 
    <informalexample>
     <programlisting role="php">
-$meinkaufswagen = new Mein_Einkaufswagen; // Kreiere einen Einkaufswagen
-$meinkaufswagen->setze_besitzer ("kris"); // Name dieser Klasse
-print $meinkaufswagen->besitzer;          // schreibe den Namen des Besitzers
-$meinkaufswagen->fuege_hinzu ("10", 1);   // (Siehe oben, vererbt 
-                                          // von Einkaufswagen)
+<![CDATA[
+$ncart = new Named_Cart;    // Create a named cart
+$ncart->set_owner("kris");  // Name that cart
+print $ncart->owner;        // print the cart owners name
+$ncart->add_item("10", 1);  // (inherited functionality from cart)
+]]>
     </programlisting>
    </informalexample>
+
+  </sect1>
+
+  <sect1 id="language.oop.constructor">
+   <title><literal>Constructors</literal></title>
+
+   <caution>
+    <simpara>
+     In PHP 3 and PHP 4 constructors behave differently. The PHP 4
+     semantics are strongly preferred.
+    </simpara>
+   </caution>
+
    <para>
-    Innerhalb der Funktionen einer Klasse bezeichnet die Variable
-    $this das aktuelle Objekt. Sie können mit $this->irgendwas auf
-    dessen Variablen und Funktionen zugreifen.
-   </para>
-   <para>
-    Konstruktoren sind Funktionen eine Klasse, die beim Erschaffen
-    eines neuen Objektes automatisch aufgerufen werden.  Eine Funktion
-    wird zu einem Konstruktor, wenn Sie den gleichen Namen wie die
-    Klasse trägt.
+    Constructors are functions in a class that are automatically
+    called when you create a new instance of a class with
+    <literal>new</literal>. In PHP 3, a
+    function becomes a constructor when it has the same name as 
+    the class. In PHP 4, a function becomes a constructor, when
+    it has the same name as the class it is defined in - the
+    difference is subtle, but crucial (see below).
    </para>
+ 
    <informalexample>
     <programlisting role="php">
-class Auto_Einkaufswagen extends Einkaufswagen {
-    function Auto_Einkaufswagen () {
-        $this->fuege_hinzu ("10", 1);
+<![CDATA[
+// Works in PHP 3 and PHP 4.
+class Auto_Cart extends Cart
+{
+    function Auto_Cart()
+    {
+        $this->add_item ("10", 1);
     }
 }
+]]>
     </programlisting>
    </informalexample>
+ 
    <para>
-    Die Klasse Auto_Einkaufswagen entspricht der Klasse Einkaufswagen
-    plus einen Konstruktor, der bereits für eine erste Füllung 
-    (1 Artikel der Nummer 10) gesorgt hat. Jeder neu erzeugte 
-    Auto_Einkaufswagen enthält so von vorneherein diesen Artikel.
-    Konstruktoren können auch Parameter enthalten. Aber diese Parameter
-    sind optional, und können so nützlicher eingesetzt werden.
+    This defines a class Auto_Cart that is a Cart plus a constructor
+    which initializes the cart with one item of article number "10"
+    each time a new Auto_Cart is being made with "new". Constructors
+    can take arguments and these arguments can be optional, which
+    makes them much more useful. To be able to still use the class
+    without parameters, all parameters to constructors should be
+    made optional by providing default values.
    </para>
+ 
    <informalexample>
     <programlisting role="php">
-class Konstruktor_Einkaufswagen extends Einkaufswagen {
-    function Konstruktor_Einkaufswagen ($produkt = "10", $anzahl = 1) {
-        $this->fuege_hinzu ($produkt, $anzahl);
+<![CDATA[
+// Works in PHP 3 and PHP 4.
+class Constructor_Cart extends Cart
+{
+    function Constructor_Cart($item = "10", $num = 1)
+    {
+        $this->add_item ($item, $num);
     }
 }
  
-// Kaufe wieder den gleichen alten Kram ein.
+// Shop the same old boring stuff.
  
-$standard_einkaufswagen   = new Konstruktor_Einkaufswagen;
+$default_cart = new Constructor_Cart;
  
-// Kaufe etwas bestimmtes ein ...
+// Shop for real...
  
-$anderer_Einkaufswagen = new Konstruktor_Einkaufswagen ("20", 17);
+$different_cart = new Constructor_Cart("20", 17);
+]]>
     </programlisting>
    </informalexample>
+
    <caution>
     <simpara>
-     Bei abgeleiteten Klassen wird der Konstruktor der Ursprungsklasse
-     nicht automatisch aufgerufen, wenn der Konstruktor der
-     abgeleiteten Klasse aufgerufen wird.
+     In PHP 3, derived classes and constructors have a number of
+     limitations. The following examples should be read carefully
+     to understand these limitations.
+    </simpara> 
+   </caution>
+   
+   <informalexample>
+    <programlisting role="php">
+<![CDATA[
+class A
+{
+    function A()
+    {
+      echo "I am the constructor of A.<br>\n";
+    }
+}
+
+class B extends A
+{
+    function C()
+    {
+        echo "I am a regular function.<br>\n";
+    }
+}
+
+// no constructor is being called in PHP 3.
+$b = new B;
+]]>
+    </programlisting>
+   </informalexample>
+
+   <para>
+    In PHP 3, no constructor is being called in the above example.
+    The rule in PHP 3 is: 'A constructor is a function of the same
+    name as the class.'. The name of the class is B, and there is
+    no function called B() in class B. Nothing happens.
+   </para>
+   
+   <para>
+    This is fixed in PHP 4 by introducing another rule: If a class
+    has no constructor, the constructor of the base class is being
+    called, if it exists. The above example would have printed
+    'I am the constructor of A.&lt;br>' in PHP 4.
+   </para>
+
+   <informalexample>
+    <programlisting role="php">
+<![CDATA[
+class A
+{
+    function A()
+    {
+        echo "I am the constructor of A.<br>\n";
+    }
+
+    function B()
+    {
+        echo "I am a regular function named B in class A.<br>\n";
+        echo "I am not a constructor in A.<br>\n";
+    }
+}
+
+class B extends A
+{
+    function C()
+    {
+        echo "I am a regular function.<br>\n";
+    }
+}
+
+// This will call B() as a constructor.
+$b = new B;
+]]>
+    </programlisting>
+   </informalexample>
+   
+   <para>
+    In PHP 3, the function B() in class A will suddenly become a
+    constructor in class B, although it was never intended to be.
+    The rule in PHP 3 is: 'A constructor is a function of the same
+    name as the class.'. PHP 3 does not care if the function is
+    being defined in class B, or if it has been inherited.
+   </para>
+   
+   <para>
+    This is fixed in PHP 4 by modifying the rule to: 'A constructor
+    is a function of the same name as the class it is being defined
+    in.'. Thus in PHP 4, the class B would have no constructor function
+    of its own and the constructor of the base class would have been
+    called, printing 'I am the constructor of A.&lt;br>'.
+   </para>
+   
+   <caution>
+    <simpara>
+     Neither PHP 3 nor PHP 4 call constructors of the base class 
+     automatically from a constructor of a derived class. It is
+     your responsibility to propagate the call to constructors
+     upstream where appropriate.
     </simpara>
    </caution>
+   
+   <note>
+    <simpara>
+     There are no destructors in PHP 3 or PHP 4. You may use
+     <function>register_shutdown_function</function> instead
+     to simulate most effects of destructors.
+    </simpara>
+   </note>
+   
+   <para>
+    Destructors are functions that are called automatically
+    when an object is destroyed, either with <function>unset</function>
+    or by simply going out of scope. There are no destructors
+    in PHP.
+   </para>
   </sect1>
+
+ <sect1 id="keyword.paamayim-nekudotayim"><!-- :-) -->
+   <title><literal>::</literal></title>
+
+   <caution>
+    <simpara>
+     The following is valid for PHP 4 only.
+    </simpara>
+   </caution>
+
+   <para>
+    Sometimes it is useful to refer to functions and variables
+    in base classes or to refer to functions in classes that
+    have not yet any instances. The :: operator is being used
+    for this.
+   </para>
+   
+   <informalexample>
+    <programlisting role="php">
+<![CDATA[
+class A
+{
+    function example()
+    {
+        echo "I am the original function A::example().<br>\n";
+    }
+}
+
+class B extends A
+{
+    function example()
+    {
+        echo "I am the redefined function B::example().<br>\n";
+        A::example();
+    }
+}
+
+// there is no object of class A.
+// this will print
+//   I am the original function A::example().<br>
+A::example();
+
+// create an object of class B.
+$b = new B;
+
+// this will print 
+//   I am the redefined function B::example().<br>
+//   I am the original function A::example().<br>
+$b->example();
+]]>
+    </programlisting>
+   </informalexample>
+
+   <para>
+    The above example calls the function example() in
+    class A, but there is no object of class A, so that
+    we cannot write $a->example() or similar. Instead we
+    call example() as a 'class function', that is, as a
+    function of the class itself, not any object of that
+    class.
+   </para>
+   
+   <para>
+    There are class functions, but there are no class variables.
+    In fact, there is no object at all at the time of the call.
+    Thus, a class function may not use any object variables (but
+    it can use local and global variables), and it may no use
+    $this at all.
+   </para>
+
+   <para>
+    In the above example, class B redefines the function example(). 
+    The original definition in class A is shadowed
+    and no longer available, unless you are refering specifically
+    to the implementation of example() in class A using the 
+    ::-operator. Write A::example() to do this (in fact, you
+    should be writing parent::example(), as shown in the next
+    section).
+   </para>
+   
+   <para>
+    In this context, there is a current object and it may
+    have object variables. Thus, when used from WITHIN an
+    object function, you may use $this and object variables.
+   </para>
+
+ </sect1>
+
+ <sect1 id="keyword.parent">
+   <title><literal>parent</literal></title>
+
+  <para>
+   You may find yourself writing code that refers to
+   variables and functions in base classes. This is
+   particularly true if your derived class is a refinement
+   or specialisation of code in your base class. 
+  </para>
+  
+  <para>
+   Instead of using the literal name of the base class in your
+   code, you should be using the special name
+   <literal>parent</literal>, which refers to the name of your
+   base class as given in the <literal>extends</literal>
+   declation of your class. By doing this, you avoid using the
+   name of your base class in more than one place. Should
+   your inheritance tree change during implementation, the
+   change is easily made by simply changing the 
+   <literal>extends</literal> declaration of your class.
+  </para>
+
+  <informalexample>
+   <programlisting role="php">
+<![CDATA[
+class A
+{
+    function example()
+    {
+        echo "I am A::example() and provide basic functionality.<br>\n";
+    }
+}
+
+class B extends A
+{
+    function example()
+    {
+        echo "I am B::example() and provide additional functionality.<br>\n";
+        parent::example();
+    }
+}
+
+$b = new B;
+
+// This will call B::example(), which will in turn call A::example().
+$b->example();
+]]>
+   </programlisting>
+  </informalexample>
+ </sect1>
+
+ <sect1 id="language.oop.serialization">
+  <title>Serializing objects - objects in sessions</title>
+
+  <note>
+   <simpara>
+    In PHP 3, objects will lose their class association
+    throughout the process of serialization and unserialization. 
+    The resulting variable is of type object, but has no class
+    and no methods, thus it is pretty useless (it has become
+    just like an array with a funny syntax).
+   </simpara>
+  </note>
+
+  <caution>
+   <simpara>
+    The following information is valid for PHP 4 only. 
+   </simpara>
+  </caution>
+
+  <para>
+   <function>serialize</function> returns a string containing a
+   byte-stream representation of any value that can be stored in
+   PHP. <function>unserialize</function> can use this string to
+   recreate the original variable values. Using serialize to
+   save an object will save all variables in an object.  The
+   functions in an object will not be saved, only the name of
+   the class.
+  </para>
+  
+  <para>
+   In order to be able to <function>unserialize</function> an
+   object, the class of that object needs to be defined. That
+   is, if you have an object $a of class A on page1.php and
+   serialize this, you'll get a string that refers to class A
+   and contains all values of variabled contained in $a. If
+   you want to be able to unserialize this on page2.php,
+   recreating $a of class A, the definition of class A must
+   be present in page2.php. This can be done for example
+   by storing the class defintion of class A in an include
+   file and including this file in both page1.php and page2.php.
+  </para>
+  
+  <informalexample>
+   <programlisting role="php">
+<![CDATA[
+classa.inc:
+  class A 
+  {
+      var $one = 1;
+    
+      function show_one()
+      {
+          echo $this->one;
+      }
+  }
+  
+page1.php:
+  include("classa.inc");
+  
+  $a = new A;
+  $s = serialize($a);
+  // store $s somewhere where page2.php can find it.
+  $fp = fopen("store", "w");
+  fputs($fp, $s);
+  fclose($fp);
+
+page2.php:
+  // this is needed for the unserialize to work properly.
+  include("classa.inc");
+
+  $s = implode("", @file("store"));
+  $a = unserialize($s);
+
+  // now use the function show_one() of the $a object.  
+  $a->show_one();
+]]>
+   </programlisting>
+  </informalexample>
+  
+  <para>
+   If you are using sessions and use <function>session_register</function>
+   to register objects, these objects are serialized automatically
+   at the end of each PHP page, and are unserialized automatically on
+   each of the following pages. This basically means that these objects
+   can show up on any of your pages once they become part of your
+   session.
+  </para>
+  
+  <para>
+   It is strongly recommended that you include the class
+   definitions of all such registered objects on all of your
+   pages, even if you do not actually use these classes on all
+   of your pages. If you don't and an object is being
+   unserialized without its class definition being present, it
+   will lose its class association and become an object of class
+   <literal>stdClass</literal> without any functions available
+   at all, that is, it will become quite useless.
+  </para>
+  
+  <para>
+   So if in the example above $a became part of a session by
+   running <literal>session_register("a")</literal>, you should
+   include the file <literal>classa.inc</literal> on all of your
+   pages, not only page1.php and page2.php.
+  </para>
+ </sect1>
+
+ <sect1 id="language.oop.magic-functions">
+  <title>The magic functions <literal>__sleep</literal> and 
+<literal>__wakeup</literal></title>
+
+  <para>
+   <function>serialize</function> checks if your class has a function with
+   the magic name <literal>__sleep</literal>. If so, that function is
+   being run prior to any serialization. It can clean up the object
+   and is supposed to return an array with the names of all variables
+   of that object that should be serialized.
+  </para>
+  
+  <para>
+   The intended use of <literal>__sleep</literal> is to close any
+   database connections that object may have, committing pending
+   data or perform similar cleanup tasks. Also, the function is
+   useful if you have very large objects which need not be
+   saved completely.
+  </para>
+  
+  <para>
+   Conversely, <function>unserialize</function> checks for the
+   presence of a function with the magic name 
+   <literal>__wakeup</literal>. If present, this function can
+   reconstruct any resources that object may have.
+  </para>
+  
+  <para>
+    The intended use of <literal>__wakeup</literal> is to
+    reestablish any database connections that may have been lost
+    during serialization and perform other reinitialization
+    tasks.
+  </para>
+ </sect1>
+  
+ <sect1 id="language.oop.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">
+<![CDATA[
+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>
+    
+   <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>=&amp;</literal> operator...
+
+    <informalexample>
+     <programlisting role="php">
+<![CDATA[
+$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>
+   <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.
+
+    <informalexample>
+     <programlisting role="php">
+<![CDATA[
+// 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 */
+]]>
+     </programlisting>
+    </informalexample>   
+   </para>   
+   <para>
+   Another final example, try to understand it.
+   
+    <informalexample>
+     <programlisting role="php">
+<![CDATA[
+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>
  
 <!-- Keep this comment at the end of the file
@@ -166,4 +919,7 @@
 sgml-local-catalogs:nil
 sgml-local-ecat-files:nil
 End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
 -->


Reply via email to