diff --git a/language/oop.xml b/language/oop.xml
index eeb14fe7cc..e09d3fb3ca 100644
--- a/language/oop.xml
+++ b/language/oop.xml
@@ -41,11 +41,39 @@ class Cart {
items from this cart.
+
+
+ The following cautionary note are valid for PHP4.
+
+
+
+ The name stdClass is used interally by
+ Zend and is reserved. You cannot have a class named
+ stdClass in PHP.
+
+
+
+ The function names __sleep and
+ __wakeup 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.
+
+
+
+ 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.
+
+
+
In PHP 4, only constant initializers for var
- variables are allowed. Use constructors for non-constant
- initializers.
+ 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).
@@ -80,19 +108,85 @@ class Cart {
-$cart = new Cart;
-$cart->add_item("10", 1);
+ $cart = new Cart;
+ $cart->add_item("10", 1);
+
+ $another_cart = new Cart;
+ $another_cart->add_item("0815", 3);
- This creates an object $cart of the class Cart. The function
- add_item() of that object is being called to add 1 item of article
- number 10 to the cart. Classes can be extensions of
- other classes. The extended or derived class has all variables and
- functions of the base class and what you add in the extended
- definition. This is done using the extends keyword. Multiple
- inheritance is not supported.
+ 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.
+
+
+
+ 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 like
+ directories in a filesystem, where you can have two different
+ files README.TXT, as long as they are in different directories,
+ and you'll have to type the full pathname in order to reach each
+ file from the toplevel directory. 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.
+
+
+
+
+// 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 $ncart->items
+$myvar = 'items';
+$cart->$myvar = array("10" => 1);
+
+
+
+
+ Within a class, 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. 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'.
+
+
+
+
+ extends
+
+
+ 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'.
@@ -123,36 +217,30 @@ print $ncart->owner; // print the cart owners name
$ncart->add_item ("10", 1); // (inherited functionality from cart)
-
-
- Within functions of a class the variable $this means this
- object. You have to use $this->something to access any variable or
- function named something within your current object. Both in and
- outside of the object you do not need a $ when accessing an object's
- properties.
-
-
-
-$ncart->owner = "chris"; // no $
+
-$ncart->$owner = "chris";
-// this is invalid because $ncart->$owner = $ncart->""
+
+ Constructors
-$myvar = 'owner';
-$ncart->$myvar = "chris";
-// this is valid because $ncart->$myvar = $ncart->owner
-
-
+
+
+ In PHP3 and PHP4 constructors behave differently. The PHP4
+ semantics are strongly preferred.
+
+
Constructors are functions in a class that are automatically
- called when you create a new instance of a class. A function
- becomes a constructor when it has the same name as the class.
+ called when you create a new instance of a class. In PHP3, a
+ function becomes a constructor when it has the same name as
+ the class. In PHP4, a function becomes a constructor, when
+ it has the same name as the class it is defined in.
+// Works in PHP3 and PHP4.
class Auto_Cart extends Cart {
function Auto_Cart () {
$this->add_item ("10", 1);
@@ -166,11 +254,14 @@ class Auto_Cart extends Cart {
which initializes the cart with one item of article number "10"
each time a new Auto_Cart is being made with "new". Constructors
can also take arguments and these arguments can be optional, which
- makes them much more useful.
+ 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.
+// Works in PHP3 and PHP4.
class Constructor_Cart extends Cart {
function Constructor_Cart ($item = "10", $num = 1) {
$this->add_item ($item, $num);
@@ -186,15 +277,364 @@ $default_cart = new Constructor_Cart;
$different_cart = new Constructor_Cart ("20", 17);
-
+
- For derived classes, the constructor of the parent class is not
- automatically called when the derived class's constructor is
- called.
+ In PHP3, derived classes and constructors have a number of
+ limitations. The following examples should be read carefully
+ to understand these limitations.
+
+
+
+class A {
+ function A() {
+ echo "I am the constructor of A.<br>\n";
+ }
+}
+
+class B extends A {
+ function C() {
+ "I am a regular function.<br>\n";
+ }
+}
+
+// no constructor is being called in PHP3.
+$b = new B;
+
+
+
+
+ In PHP3, no constructor is being called in the above example.
+ The rule in PHP3 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.
+
+
+
+ This is fixed in PHP4 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 PHP4.
+
+
+
+
+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;
+
+
+
+
+ In PHP3, the function B() in class A will suddenly become a
+ constructor in class B, although it was never intended to be.
+ The rule in PHP3 is: 'A constructor is a function of the same
+ name as the class.'. PHP3 does not care if the function is
+ being defined in class B, or if it has been inherited.
+
+
+
+ This is fixed in PHP4 by modifying the rule to: 'A constructor
+ is a function of the same name as the class it is being defined
+ in.'. Thus in PHP4, 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>'.
+
+
+
+
+ Neither PHP3 nor PHP4 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.
+
+
+
+
+
+ There are no destructors in PHP3 or PHP4. You may use
+ register_shutdown_function instead
+ to simulate most effects of destructors.
+
+
+
+
+ Destructors are functions that are called automatically
+ when a variable is destroyed, either with unset
+ or by simply going out of scope. There are no destructors
+ in PHP.
+
+
+
+ ::
+
+
+
+ The following is valid for PHP4 only.
+
+
+
+
+ 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.
+
+
+
+
+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();
+
+
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+ 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 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.
+
+
+
+
+
+ parent
+
+
+ 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.
+
+
+
+ Instead of using the literal name of the base class in your
+ code, you should be using the special name
+ parent, which refers to the name of your
+ base class as given in the extends
+ 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
+ extends declaration of your class.
+
+
+
+
+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();
+
+
+
+
+
+ Serializing objects - objects in sessions
+
+
+
+ The following information is valid for PHP4 only. In
+ PHP3, an
+
+
+
+
+ serialize returns a string containing a
+ byte-stream representation of any value that can be stored in
+ PHP. unserialize 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.
+
+
+
+ In order to be able to unserialize 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.
+
+
+
+
+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");
+ echo $s;
+ fclose($fp);
+
+page2.php:
+ // this is needed for the unserialize to work properly.
+ include("classa.inc");
+
+ $s = implode("", @file("store"));
+ unserialize($s);
+
+ // now use the function show_one of the $a object.
+ $a->show_one();
+
+
+
+
+ If you are using sessions and use session_register
+ 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.
+
+
+
+ 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
+ stdClass without any functions available
+ at all, that is, it will become quite useless.
+
+
+
+ So if the in the example above $a became part of a session by
+ running session_register("a"), you should
+ include the file classa.inc on all of your
+ pages, not only page1.php and page2.php.
+
+
+
+
+ The magic functions __sleep and __wakeup
+
+
+ serialize checks if your class has a function with
+ the magic name __sleep. 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.
+
+
+
+ The intended use of __sleep 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.
+
+
+
+ Conversely, unserialize checks for the
+ presence of a function with the magic name
+ __wakeup. If present, this function can
+ reconstruct any ressources that object may have.
+
+
+
+ The intended use of __wakeup is to
+ reestablish any database connections that may have been lost
+ during serialization and perform other reinitialization
+ tasks.
+
+
References inside the constructor