nlopess Mon Jul 26 07:47:30 2004 EDT
Modified files: /phpdoc/en/appendices migration5.xml Log: remove the oop docs and link to the new oop5 language reference
http://cvs.php.net/diff.php/phpdoc/en/appendices/migration5.xml?r1=1.25&r2=1.26&ty=u Index: phpdoc/en/appendices/migration5.xml diff -u phpdoc/en/appendices/migration5.xml:1.25 phpdoc/en/appendices/migration5.xml:1.26 --- phpdoc/en/appendices/migration5.xml:1.25 Wed Jul 21 05:05:12 2004 +++ phpdoc/en/appendices/migration5.xml Mon Jul 26 07:47:30 2004 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="iso-8859-1"?> -<!-- $Revision: 1.25 $ --> +<!-- $Revision: 1.26 $ --> <appendix id="migration5"> <title>Migrating from PHP 4 to PHP 5</title> @@ -799,1015 +799,14 @@ out of the box, or with very few modifications. </para> <para> + The new Object Model is documented at the <link + linkend="language.oop5">Language Reference</link>. + </para> + <para> See also the <link linkend="ini.zend.ze1-compatibility-mode"> zend.ze1_compatibility_mode</link> directive for compatability with PHP 4. </para> - - <section id='migration.oop.members'> - <title>Private and Protected Members</title> - <para> - PHP 5 introduces private and protected member variables, they allow you - to define the visibility of class properties. - </para> - <example> - <title>Private and Protected Members accesibility</title> - <simpara> - Protected member variables can be accessed in classes extending the - class they are declared in, whereas private member variables can only be - accessed by the class they belong to. - </simpara> - <programlisting role="php"> -<![CDATA[ -<?php -class MyClass { - private $Hello = "Hello, World!\n"; - protected $Bar = "Hello, Foo!\n"; - protected $Foo = "Hello, Bar!\n"; - - function printHello() { - print "MyClass::printHello() " . $this->Hello; - print "MyClass::printHello() " . $this->Bar; - print "MyClass::printHello() " . $this->Foo; - } -} - -class MyClass2 extends MyClass { - protected $Foo; - - function printHello() { - MyClass::printHello(); /* Should print */ - print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */ - print "MyClass2::printHello() " . $this->Bar; /* Shouldn't print (not declared)*/ - print "MyClass2::printHello() " . $this->Foo; /* Should print */ - } -} - -$obj = new MyClass(); -print $obj->Hello; /* Shouldn't print out anything */ -print $obj->Bar; /* Shouldn't print out anything */ -print $obj->Foo; /* Shouldn't print out anything */ -$obj->printHello(); /* Should print */ - -$obj = new MyClass2(); -print $obj->Hello; /* Shouldn't print out anything */ -print $obj->Bar; /* Shouldn't print out anything */ -print $obj->Foo; /* Shouldn't print out anything */ -$obj->printHello(); -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration.oop.methods'> - <title>Private and Protected Methods</title> - <para> - With PHP 5, private and protected methods are also introduced. - </para> - <example> - <title>Protected methods example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - private function aPrivateMethod() { - echo "Foo::aPrivateMethod() called.\n"; - } - - protected function aProtectedMethod() { - echo "Foo::aProtectedMethod() called.\n"; - $this->aPrivateMethod(); - } -} - -class Bar extends Foo { - public function aPublicMethod() { - echo "Bar::aPublicMethod() called.\n"; - $this->aProtectedMethod(); - } -} - -$o = new Bar; -$o->aPublicMethod(); -?> -]]> - </programlisting> - </example> - <simpara> - Old code that has no user-defined classes or functions named - "public", "protected" or "private" should - run without modifications. - </simpara> - </section> - - <section id='migration.oop.abstract'> - <title>Abstract Classes and Methods</title> - <para> - PHP 5 also introduces abstract classes and methods. An abstract method - only declares the method's signature and does not provide an - implementation. A class that contains abstract methods needs to be - declared abstract. - </para> - <example> - <title>Abstract class example</title> - <programlisting role="php"> -<![CDATA[ -<?php -abstract class AbstractClass { - abstract public function test(); -} - -class ImplementedClass extends AbstractClass { - public function test() { - echo "ImplementedClass::test() called.\n"; - } -} - -$o = new ImplementedClass; -$o->test(); -?> -]]> - </programlisting> - </example> - <simpara> - Abstract classes cannot be instantiated. Old code that has no - user-defined classes or functions named 'abstract' should run without - modifications. - </simpara> - </section> - - <section id='migration.oop.interfaces'> - <title>Interfaces</title> - <para> - PHP 5 introduces interfaces. A class may implement an arbitrary list of - interfaces. - </para> - <example> - <title>Interface example</title> - <programlisting role="php"> -<![CDATA[ -<?php -interface Throwable { - public function getMessage(); -} - -class MyException implements Throwable { - public function getMessage() { - // ... - } -} -?> -]]> - </programlisting> - </example> - <simpara> - Old code that has no user-defined classes or functions named 'interface' - or 'implements' should run without modifications. - </simpara> - </section> - - <section id='migration.oop.typehints'> - <title>Class Type Hints</title> - <para> - While remaining loosely typed PHP 5 introduces the ability to use class - type hints to declare the expected class of objects that are passed as - parameters to a method. - </para> - <example> - <title>Class type hinting example</title> - <programlisting role="php"> -<![CDATA[ -<?php -interface Foo { - function a(Foo $foo); -} - -interface Bar { - function b(Bar $bar); -} - -class FooBar implements Foo, Bar { - function a(Foo $foo) { - // ... - } - - function b(Bar $bar) { - // ... - } -} - -$a = new FooBar; -$b = new FooBar; - -$a->a($b); -$a->b($b); -?> -]]> - </programlisting> - </example> - <simpara> - These class type hints are not checked upon compilation, as would be the - case in a typed language, but during runtime. This means that: - </simpara> - <informalexample> - <programlisting role="php"> -<![CDATA[ -<?php -function foo(ClassName $object) { - // ... -} -?> -]]> - </programlisting> - </informalexample> - <simpara>is equivalent to:</simpara> - <informalexample> - <programlisting role="php"> -<![CDATA[ -<?php -function foo($object) { - if (!($object instanceof ClassName)) { - die("Argument 1 must be an instance of ClassName"); - } -} -?> -]]> - </programlisting> - </informalexample> - </section> - - <section id='migration5.oop.final'> - <title>final</title> - <para> - PHP 5 introduces the "final" keyword to declare final members and - methods. Methods and members declared final cannot be overridden by - sub-classes. - </para> - <example> - <title>final method</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - final function bar() { - // ... - } -} -?> -]]> - </programlisting> - </example> - <para> - It is furthermore possible to make a class final. Doing this prevents a - class from being specialized (it cannot be inherited by another class). - There's no need to declare the methods of a final class themselves as - final. - </para> - <example> - <title>final class</title> - <programlisting role="php"> -<![CDATA[ -<?php -final class Foo { - // class definition -} - -// the next line is impossible -// class Bork extends Foo {} -?> -]]> - </programlisting> - </example> - <para> - Properties can not be final. - </para> - <para> - Old code that has no user-defined classes or functions named 'final' - should run without modifications. - </para> - </section> - - <section id='migration5.oop.cloning'> - <title>Objects Cloning</title> - <para> - PHP 4 offered no way a user could decide what copy constructor to run - when an object is duplicated. During duplication, PHP 4 did a bit for bit - copy making an identical replica of all the object's properties. - </para> - <para> - Creating a copy of an object with fully replicated properties is not - always the wanted behavior. A good example of the need for copy - constructors, is if you have an object which represents a GTK window and - the object holds the resource of this GTK window, when you create a - duplicate you might want to create a new window with the same properties - and have the new object hold the resource of the new window. Another - example is if your object holds a reference to another object which it - uses and when you replicate the parent object you want to create a new - instance of this other object so that the replica has its own separate - copy. - </para> - <para> - An object copy is created by using the clone keyword (which calls the - object's <function>__clone</function> method if possible). An object's - <function>__clone</function> method cannot be called directly. - </para> - <para> - When the developer asks to create a new copy of an object, PHP 5 will - check if a <function>__clone</function> method has been defined or not. - If not, it will call a default __clone() which will copy all of the object's - properties. If a <function>__clone</function> method is defined, then it - will be responsible to set the necessary properties in the created object. - For convenience, the engine will supply a function that imports all of the - properties from the source object, so that they can start with a by-value - replica of the source object, and only override properties that need to be - changed. - </para> - <example> - <title>Objects cloning</title> - <programlisting role="php"> -<![CDATA[ -<?php -class MyCloneable { - static $id = 0; - - function MyCloneable() { - $this->id = self::$id++; - } - - function __clone() { - $this->address = "New York"; - $this->id = self::$id++; - } -} - -$obj = new MyCloneable(); - -$obj->name = "Hello"; -$obj->address = "Tel-Aviv"; - -print $obj->id . "\n"; - -$obj_cloned = clone $obj; - -print $obj_cloned->id . "\n"; -print $obj_cloned->name . "\n"; -print $obj_cloned->address . "\n"; -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.constructors'> - <title>Constructors</title> - <para> - PHP 5 allows developers to declare constructor methods for classes. - Classes which have a constructor method call this method on each - newly-created object, so it is suitable for any initialization that the - object may need before it is used. - </para> - <para> - With PHP 4, constructor methods were class methods that had the same name - as the class itself. Since it is very common to call parent constructors - from derived classes, the way PHP 4 worked made it a bit cumbersome to - move classes around in a large class hierarchy. If a class is moved to - reside under a different parent, the constructor name of that parent - changes as well, and the code in the derived class that calls the parent - constructor has to be modified. - </para> - <para> - PHP 5 introduces a standard way of declaring constructor methods by - calling them by the name <function>__construct</function>. - </para> - <example> - <title>using new unified constructors</title> - <programlisting role="php"> -<![CDATA[ -<?php -class BaseClass { - function __construct() { - print "In BaseClass constructor\n"; - } -} - -class SubClass extends BaseClass { - function __construct() { - parent::__construct(); - print "In SubClass constructor\n"; - } -} - -$obj = new BaseClass(); -$obj = new SubClass(); -?> -]]> - </programlisting> - </example> - <para> - For backwards compatibility, if PHP 5 cannot find a - <function>__construct</function> function for a given class, it will - search for the old-style constructor function, by the name of the class. - Effectively, it means that the only case that would have compatibility - issues is if the class had a method named - <function>__construct</function> which was used for different semantics. - </para> - </section> - - <section id='migration5.oop.destructors'> - <title>Destructors</title> - <para> - Having the ability to define destructors for objects can be very useful. - Destructors can log messages for debugging, close database connections - and do other clean-up work. No mechanism for object destructors existed - in PHP 4, although PHP had already support for registering functions - which should be run on request shutdown. - </para> - <para> - PHP 5 introduces a destructor concept similar to that of other - object-oriented languages, such as Java: When the last reference to an - object is destroyed the object's destructor, which is a class method - named <function>__destruct</function> that receives no parameters, is - called before the object is freed from memory. - </para> - <example> - <title>Destructor</title> - <programlisting role="php"> -<![CDATA[ -<?php -class MyDestructableClass { - function __construct() { - print "In constructor\n"; - $this->name = "MyDestructableClass"; - } - - function __destruct() { - print "Destroying " . $this->name . "\n"; - } -} - -$obj = new MyDestructableClass(); -?> -]]> - </programlisting> - </example> - <para> - Like constructors, parent destructors will not be called implicitly by - the engine. In order to run a parent destructor, one would have to - explicitly call <function>parent::__destruct</function> in the destructor - body. - </para> - </section> - - <section id='migration5.oop.constants'> - <title>Constants</title> - <para> - PHP 5 introduces per-class constants: - </para> - <example> - <title>Class constant example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - const constant = "constant"; -} - -echo "Foo::constant = " . Foo::constant . "\n"; -?> -]]> - </programlisting> - </example> - <simpara> - Old code that has no user-defined classes or functions named 'const' - will run without modifications. - </simpara> - </section> - - <section id='migration5.oop.exceptions'> - <title>Exceptions</title> - <para> - PHP 4 had no exception handling. PHP 5 introduces a exception model - similar to that of other programming languages. Note that there is - support for "catch all" but not for the "finally" clause. - </para> - <para> - Exceptions can be rethrown in catch blocks. Also it is possible to have - multiple catch blocks. In that case the caught exception is compared with - the classtype of each catch block from top to bottom and the first block - that has an 'instanceof' match gets executed. When the catch block - finishes, execution continues at the end of the last catch block. If no - catch block has an 'instanceof' match then the next try/catch block is - searched until no more try/catch blocks are available. In that case the - exception is an uncaught exception and the program terminates with - showing the exception. - </para> - <example> - <title>Exception creation example</title> - <programlisting role="php"> -<![CDATA[ -<?php -try { - throw new Exception('Hello'); -} -catch (Exception $exception) { - echo $exception; -} -?> -]]> - </programlisting> - </example> - <simpara> - Old code that has no user-defined classes or functions 'catch', 'throw' - and 'try' will run without modifications. - </simpara> - </section> - - <section id='migration5.oop.dereferencing'> - <title>Dereferencing objects returned from functions</title> - <para> - In PHP 4 it wasn't possible to dereference objects returned by functions - and make further method calls on those objects. With PHP 5, the following - is now possible: - </para> - <example> - <title>Dereferencing example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Circle { - function draw() { - print "Circle\n"; - } -} - -class Square { - function draw() { - print "Square\n"; - } -} - -function ShapeFactoryMethod($shape) { - switch ($shape) { - case "Circle": - return new Circle(); - case "Square": - return new Square(); - } -} - -ShapeFactoryMethod("Circle")->draw(); -ShapeFactoryMethod("Square")->draw(); -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.staticinit'> - <title>Static member variables initialization</title> - <para> - Static member variables of static classes can now be initialized. - </para> - <example> - <title>Static variable initialization example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class foo { - static $my_static = 5; - public $my_prop = 'bla'; -} - -print foo::$my_static; -$obj = new foo; -print $obj->my_prop; -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.staticmethods'> - <title>Static Methods</title> - <para> - PHP 5 introduces the 'static' keyword to declare a method static, thus - callable from outside the object context. - </para> - <example> - <title> Static Methods example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - public static function aStaticMethod() { - // ... - } -} - -Foo::aStaticMethod(); -?> -]]> - </programlisting> - </example> - <para> - The pseudo variable $this is not available inside a method that has been - declared static. - </para> - </section> - - <section id='migration5.oop.instanceof'> - <title>instanceof</title> - <para> - PHP 5 introduces the <literal>instanceof</literal> keyword, that - allows you to ascertain whether or not an object is an instance of - a class, or extends a class, or implements an interface. - </para> - <example> - <title><literal>instanceof</literal> example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class baseClass { } - -$a = new baseClass; - -if ($a instanceof baseClass) { - echo "Hello World"; -} -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.staticvars'> - <title>Static function variables</title> - <para> - Statics are now treated at compile-time which allows developers to - assign variables to statics by reference. This change also greatly - improves their performance but means that indirect references to statics - will not work anymore. - </para> - </section> - - <section id='migration5.oop.refparams'> - <title>Parameters passed by reference</title> - <para> - Parameters that are passed by reference to a function may now have - default values - </para> - <example> - <title /> - <programlisting role="php"> -<![CDATA[ -<?php -function my_function(&$var = null) { - if ($var === null) { - die("$var needs to have a value"); - } -} -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.autoload'> - <title><function>__autoload</function></title> - <para> - The <function>__autoload</function> interceptor function will be - automatically called when an undeclared class is to be instantiated. - The name of that class will be passed to the <function>__autoload</function> - interceptor function as its only argument. - </para> - <example> - <title><function>__autoload</function> example</title> - <programlisting role="php"> -<![CDATA[ -<?php -function __autoload($className) { - include_once $className . ".php"; -} - -$object = new ClassName; -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.overload'> - <title>Overloadable Method calls and Property accesses</title> - <para> - Both method calls and property accesses can be overloaded via the - <function>__call</function>, <function>__get</function> and - <function>__set</function> methods. These methods will only be - triggered when your object doesn't contain the property or method - your're trying to access. - </para> - <example> - <title> - <function>__get</function> and - <function>__set</function> - </title> - <programlisting role="php"> -<![CDATA[ -<?php -class Setter { - public $n; - public $x = array("a" => 1, "b" => 2, "c" => 3); - - function __get($nm) { - print "Getting [$nm]\n"; - - if (isset($this->x[$nm])) { - $r = $this->x[$nm]; - print "Returning: $r\n"; - return $r; - } else { - print "Nothing!\n"; - } - } - - function __set($nm, $val) { - print "Setting [$nm] to $val\n"; - - if (isset($this->x[$nm])) { - $this->x[$nm] = $val; - print "OK!\n"; - } else { - print "Not OK!\n"; - } - } -} - -$foo = new Setter(); -$foo->n = 1; -$foo->a = 100; -$foo->a++; -$foo->z++; -var_dump($foo); -?> -]]> - </programlisting> - <screen role="php"> -<![CDATA[ -Setting [a] to 100 -OK! -Getting [a] -Returning: 100 -Setting [a] to 101 -OK! -Getting [z] -Nothing! -Setting [z] to 1 -Not OK! -object(Setter)#1 (2) { - ["n"]=> - int(1) - ["x"]=> - array(3) { - ["a"]=> - int(101) - ["b"]=> - int(2) - ["c"]=> - int(3) - } -} -]]> - </screen> - </example> - <example> - <title><function>__call</function> example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Caller { - private $x = array(1, 2, 3); - - function __call($m, $a) { - print "Method $m called:\n"; - var_dump($a); - return $this->x; - } -} - -$foo = new Caller(); -$a = $foo->test(1, "2", 3.4, true); -var_dump($a); -?> -]]> - </programlisting> - </example> - </section> - - <section id='migration5.oop.iteration'> - <title>Iteration</title> - <para> - Objects may be iterated in an overloaded way when used with foreach. The - default behavior is to iterate over all properties. - </para> - <example> - <title>Object iteration example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - public $x = 1; - public $y = 2; -} - -$obj = new Foo; - -foreach ($obj as $prp_name => $prop_value) { - // using the property -} -?> -]]> - </programlisting> - </example> - <para> - Each class whose instances can be iterated with foreach should implement - the empty interface <literal>Traversable</literal>. Hence any object that - says it implements <literal>Traversable</literal> can be used with foreach. - </para> - <para> - The interfaces <literal>IteratorAggregate</literal> and <literal>Iterator</literal> - allows you to specify how class objects are iterated in PHP code. The first - of them simply has a method <function>getIterator</function> which must - return an array or an object that either implements the interface - <literal>Iterator</literal> or is instantiated from an internal - class that can be iterated - </para> - <example> - <title>Iterator creation example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class ObjectIterator implements Iterator { - - private $obj; - private $num; - - function __construct($obj) { - $this->obj = $obj; - } - function rewind() { - $this->num = 0; - } - function valid() { - return $this->num < $this->obj->max; - } - function key() { - return $this->num; - } - function current() { - switch($this->num) { - case 0: return "1st"; - case 1: return "2nd"; - case 2: return "3rd"; - default: return $this->num."th"; - } - } - function next() { - $this->num++; - } -} - -class Object implements IteratorAggregate { - - public $max = 3; - - function getIterator() { - return new ObjectIterator($this); - } -} - -$obj = new Object; - -// this foreach ... -foreach($obj as $key => $val) { - echo "$key = $val\n"; -} - -// matches the following 7 lines with the for directive. -$it = $obj->getIterator(); -for($it->rewind(); $it->valid(); $it->next()) { - $key = $it->current(); - $val = $it->key(); - echo "$key = $val\n"; -} -unset($it); -?> -]]> - </programlisting> - </example> - </section> - - <section id='migrating5.oop.methodconst'> - <title><literal>__METHOD__</literal> constant</title> - <para> - The new <literal>__METHOD__</literal> pseudo constant shows the current - class and method when used inside a method and the function when used outside - of a class. - </para> - <example> - <title><literal>__METHOD__</literal> use example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - function show() { - echo __METHOD__; - } -} - -class Bar extends Foo { -} - -Foo::show(); // outputs Foo::show -Bar::show(); // outputs Foo::show either since __METHOD__ is - // compile-time evaluated token - -function test() { - echo __METHOD__; -} - -test(); // outputs test -?> -]]> - </programlisting> - </example> - </section> - - <section id='migrating5.oop.tostring'> - <title><function>__toString</function> method</title> - <para> - The new <function>__toString</function> magic method allows you to - overload the object to string conversion. - </para> - <example> - <title><function>__toString</function> example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - function __toString() { - return "What ever"; - } -} - -$obj = new Foo; - -echo $obj; // call __toString() -?> -]]> - </programlisting> - </example> - </section> - - <section id='migrating5.oop.reflection'> - <title>Reflection API</title> - <para> - PHP 5 comes with a complete reflection API that adds the ability to - reverse-engineer classes, interfaces, functions and methods as well as - extensions. - </para> - <para> - The reflection API also offers ways of getting doc comments for - functions, classes and methods. - </para> - <para> - Nearly all aspects of object oriented code can be reflected by using the - reflection API which is - <ulink url="http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html"> - documented separately</ulink>. - </para> - <example> - <title>Reflection API use example</title> - <programlisting role="php"> -<![CDATA[ -<?php -class Foo { - public $prop; - function Func($name) { - echo "Hello $name"; - } -} - -reflectionClass::export('Foo'); -reflectionObject::export(new Foo); -reflectionMethod::export('Foo', 'func'); -reflectionProperty::export('Foo', 'prop'); -reflectionExtension::export('standard'); -?> -]]> - </programlisting> - </example> - </section> - </section> <section id='migrating5.errorrep'>