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"> -<?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 ->. + Thus, the names $cart->items and $another_cart->items + name two different variables. Note that the variable is + named $cart->items, not $cart->$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->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->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.<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.<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>=&</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 -->