From 58257f0979feba97c5777260f0f66caea6951387 Mon Sep 17 00:00:00 2001 From: Boris Bezrukov Date: Sun, 23 May 2004 16:30:39 +0000 Subject: [PATCH] Changes in PHP5/Zend2 inserted into OOP section git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@159464 c90b9560-bf6c-de11-be94-00142212c4b1 --- appendices/migration5.xml | 1137 ++++++++++++++++++++++++++++++++++++- 1 file changed, 1110 insertions(+), 27 deletions(-) diff --git a/appendices/migration5.xml b/appendices/migration5.xml index 1920de87f6..9c97358b33 100755 --- a/appendices/migration5.xml +++ b/appendices/migration5.xml @@ -1,15 +1,15 @@ - + Migrating from PHP 4 to PHP 5
What has changed in PHP 5 - PHP 5 and the integrated Zend Engine 2 have greatly improved PHP's + &php; 5 and the integrated Zend Engine 2 have greatly improved PHP's performance and capabilities, but great care has been taken to break as - little existing code as possible. So migrating your code from PHP 4 to 5 - should be very easy. Most existing PHP 4 code should be ready to run + little existing code as possible. So migrating your code from &php; 4 to 5 + should be very easy. Most existing &php; 4 code should be ready to run without changes, but you should still know about the few differences and take care to test your code before switching versions in production @@ -20,7 +20,7 @@
Backward Incompatible Changes - Although most existing PHP 4 code should work without changes, you should + Although most existing &php; 4 code should work without changes, you should pay attention to the following backward incompatible changes: @@ -40,7 +40,7 @@ PATH_TRANSLATED server variable is no longer set implicitly under - Apache2 SAPI in contrast to the situation in PHP 4, where it is set to + Apache2 SAPI in contrast to the situation in &php; 4, where it is set to the same value as the SCRIPT_FILENAME server variable when it is not populated by Apache. This change was made to comply with the CGI specification. Please refer to The T_ML_CONSTANT constant is no longer defined by the Tokenizer extension. If - error_reporting is set to E_ALL, PHP will generate a + error_reporting is set to E_ALL, &php; will generate a notice. Although the T_ML_CONSTANT was never used - at all, it was defined in PHP 4. In both PHP 4 and PHP 5 // and /* */ + at all, it was defined in &php; 4. In both &php; 4 and &php; 5 // and /* */ are resolved as the T_COMMENT constant. However the - PHPDoc style comments /** */ ,which starting PHP 5 are parsed by PHP, are + PHPDoc style comments /** */ ,which starting &php; 5 are parsed by &php;, are recognized as T_DOC_COMMENT. @@ -110,8 +110,8 @@ if (!$t) { - The following example was valid in PHP 4, although it will produce a fatal - error in PHP 5. + The following example was valid in &php; 4, although it will produce a fatal + error in &php; 5. @@ -137,19 +137,19 @@ class fubar {
CLI and CGI - In PHP 5 there were some changes in CLI and CGI filenames. In PHP 5, the + In &php; 5 there were some changes in CLI and CGI filenames. In &php; 5, the CGI version was renamed to php-cgi.exe (previously php.exe) and the CLI version now sits in the main directory (previously cli/php.exe). - In PHP 5 it was also introduced a new mode: + In &php; 5 it was also introduced a new mode: php-win.exe. This is equal to the CLI version, except that php-win doesn't output anything and thus provides no console (no "dos box" appears on the screen). This behavior is similar to php-gtk. - In PHP 5, the CLI version will always populate the global $argv and $argc + In &php; 5, the CLI version will always populate the global $argv and $argc variables.
@@ -179,7 +179,7 @@ LoadModule php5_module /php/php5apache2.dll
- If your webserver is running PHP in CGI mode, you should note that the + If your webserver is running &php; in CGI mode, you should note that the CGI version has changed its name from php.exe to php-cgi.exe. In Apache you should do something like this: @@ -203,7 +203,7 @@ Action application/x-httpd-php "/php/php-cgi.exe"
New Functions - In PHP 5 there are some new functions. Here is the list of them: + In &php; 5 there are some new functions. Here is the list of them: Arrays: @@ -522,7 +522,7 @@ Action application/x-httpd-php "/php/php-cgi.exe"
New Directives - There were some new &php.ini; directives introduced in PHP 5. Here is a + There were some new &php.ini; directives introduced in &php; 5. Here is a list of them: @@ -534,7 +534,7 @@ Action application/x-httpd-php "/php/php-cgi.exe" register_long_arrays - - allow/disallow PHP to register the deprecated long $HTTP_*_VARS + allow/disallow &php; to register the deprecated long $HTTP_*_VARS session.hash_function - @@ -547,7 +547,7 @@ Action application/x-httpd-php "/php/php-cgi.exe" binary hash data to something readable (from 4 to 6) - zend.ze1_compatibility_mode - Enable compatibility mode with Zend Engine 1 (PHP 4) + zend.ze1_compatibility_mode - Enable compatibility mode with Zend Engine 1 (&php; 4)
@@ -555,10 +555,10 @@ Action application/x-httpd-php "/php/php-cgi.exe"
Databases - There were some changes in PHP 5 regarding databases (MySQL and SQLite). + There were some changes in &php; 5 regarding databases (MySQL and SQLite). - In PHP 5 the MySQL client libraries are not bundled, because of license + In &php; 5 the MySQL client libraries are not bundled, because of license problems and some others. For more information, read the FAQ entry. @@ -567,24 +567,1107 @@ Action application/x-httpd-php "/php/php-cgi.exe" MySQL), which is designed to work with MySQL 4.1 and above. - Since PHP 5, the SQLite extension is - built-in PHP. SQLite is an embeddable SQL database engine and is not a + Since &php; 5, the SQLite extension is + built-in &php;. SQLite is an embeddable SQL database engine and is not a client library used to connect to a big database server (like MySQL or PostgreSQL). The SQLite library reads and writes directly to and from the database files on disk.
+
New Object Model - In PHP 5 there is a new Object Model. PHP's handling of objects has been + In &php; 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. - Please read http://www.php.net/zend-engine-2.php - for more info. + In previous versions of &php;, objects were handled like primitive types + (for instance integers and strings). The drawback of this method was that + semantically the whole object was copied when a variable was assigned, or + pass as a parameter to a method. In the new approach, objects are + referenced by handle, and not by value (one can think of a handle as an + object's identifier). + + Many &php; programmers aren't even aware of the copying quirks of the old + object model and, therefore, the majority of &php; applications will work + out of the box, or with very few modifications. + + +
+ Private and Protected Members + + &php; 5 introduces private and protected member variables, they allow you + to define the visibility of class properties. + + + Private and Protected Members accesibility + + 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. + + +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(); +?> +]]> + + +
+ +
+ Private and Protected Methods + + With &php; 5, private and protected methods are also introduced. + + + Protected methods example + +aPrivateMethod(); + } +} + +class Bar extends Foo { + public function aPublicMethod() { + echo "Bar::aPublicMethod() called.\n"; + $this->aProtectedMethod(); + } +} + +$o = new Bar; +$o->aPublicMethod(); +?> +]]> + + + + Old code that has no user-defined classes or functions named + "public", "protected" or "private" should + run without modifications. + +
+ +
+ Abstract Classes and Methods + + &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. + + + Abstract class example + +test(); +?> +]]> + + + + Abstract classes cannot be instantiated. Old code that has no + user-defined classes or functions named 'abstract' should run without + modifications. + +
+ +
+ Interfaces + + &php; 5 introduces interfaces. A class may implement an arbitrary list of + interfaces. + + + Interface example + + +]]> + + + + Old code that has no user-defined classes or functions named 'interface' + or 'implements' should run without modifications. + +
+ +
+ Class Type Hints + + 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. + + + Class type hinting example + +a($b); +$a->b($b); +?> +]]> + + + + These class type hints are not checked upon compilation, as would be the + case in a typed language, but during runtime. This means that: + + + + +]]> + + + is equivalent to: + + + +]]> + + +
+ +
+ final + + &php; 5 introduces the "final" keyword to declare final members and + methods. Methods and members declared final cannot be overridden by + sub-classes. + + + final method + + +]]> + + + + 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. + + + final class + + +]]> + + + + Properties can not be final. + + + Old code that has no user-defined classes or functions named 'final' + should run without modifications. + +
+ +
+ Objects Cloning + + &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. + + + 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. + + + An object copy is created by using the clone keyword (which calls the + object's __clone method if possible). An object's + __clone method cannot be called directly. + + + When the developer asks to create a new copy of an object, &php; 5 will + check if a __clone 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 __clone 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. + + + Objects cloning + +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"; +?> +]]> + + +
+ +
+ Constructors + + &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. + + + 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. + + + &php; 5 introduces a standard way of declaring constructor methods by + calling them by the name __construct. + + + using new unified constructors + + +]]> + + + + For backwards compatibility, if &php; 5 cannot find a + __construct 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 + __construct which was used for different semantics. + +
+ +
+ Destructors + + 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. + + + &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 __destruct that receives no parameters, is + called before the object is freed from memory. + + + Destructor + +name = "MyDestructableClass"; + } + + function __destruct() { + print "Destroying " . $this->name . "\n"; + } +} + +$obj = new MyDestructableClass(); +?> +]]> + + + + 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 parent::__destruct in the destructor + body. + +
+ +
+ Constants + + &php; 5 introduces per-class constants: + + + Class constant example + + +]]> + + + + Old code that has no user-defined classes or functions named 'const' + will run without modifications. + +
+ +
+ Exceptions + + &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. + + + 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. + + + Exception creation example + +exception = $exception; + } + + function Display() { + print "MyException: $this->exception\n"; + } +} + +class MyExceptionFoo extends MyException { + function __construct($exception) { + $this->exception = $exception; + } + + function Display() { + print "MyException: $this->exception\n"; + } +} + +try { + throw new MyExceptionFoo('Hello'); +} +catch (MyException $exception) { + $exception->Display(); +} +catch (Exception $exception) { + echo $exception; +} +?> +]]> + + + + Even though the above example shows that it is possible to define + exception classes that don't inherit from Exception it is best to do so. + This is because the internal Exception class can gather a lot of + information otherwise not available. The &php; code emulation code would + look something like shown below. The comments show the meaning of each + property and hence their getter methods. As the code shows it is possible + to read any available information by using the getter methods. But since + some of the methods are used internally they are marked final. All in all + the class is very restrictive because it must be ensured that anything + used internally always works as expected. + + + Base exceptions class + +message = $message; + } + $this->code = $code; + $this->file = __FILE__; // of throw clause + $this->line = __LINE__; // of throw clause + $this->trace = debug_backtrace(); + $this->string = StringFormat($this); + } + + protected $message = 'Unknown exception'; // exception message + protected $code = 0; // user defined exception code + protected $file; // source filename of exception + protected $line; // source line of exception + + private $trace; // backtrace of exception + private $string; // internal only!! + + final function getMessage() { + return $this->message; + } + final function getCode() { + return $this->code; + } + final function getFile() { + return $this->file; + } + final function getTrace() { + return $this->trace; + } + final function getTraceAsString() { + return self::TraceFormat($this); + } + function _toString() { + return $this->string; + } + static private function StringFormat(Exception $exception) { + // ... a function not available in PHP scripts + // that returns all relevant information as a string + } + static private function TraceFormat(Exception $exception) { + // ... a function not available in PHP scripts + // that returns the backtrace as a string + } +} +?> +]]> + + + + If you derive your exception classes from this Exception base class your + exceptions will be nicely shown in the built-in handler for uncaught + exceptions. + + + Old code that has no user-defined classes or functions 'catch', 'throw' + and 'try' will run without modifications. + +
+ +
+ Dereferencing objects returned from functions + + 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: + + + Dereferencing example + +draw(); +ShapeFactoryMethod("Square")->draw(); +?> +]]> + + +
+ +
+ Static member variables initialization + + Static member variables of static classes can now be initialized. + + + Static variable initialization example + +my_prop; +?> +]]> + + +
+ +
+ Static Methods + + &php; 5 introduces the 'static' keyword to declare a method static, thus + callable from outside the object context. + + + Static Methods example + + +]]> + + + + The pseudo variable $this is not available inside a method that has been + declared static. + +
+ +
+ instanceof + + &php; 5 introduces the instanceof 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. + + + <literal>instanceof</literal> example + + +]]> + + +
+ +
+ Static function variables + + 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. + +
+ +
+ Parameters passed by reference + + Parameters that are passed by reference to a function may now have + default values + + + + <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> + + The __autoload interceptor function will be + automatically called when an undeclared class is to be instantiated. + The name of that class will be passed to the __autoload + interceptor function as its only argument. + + + <function>__autoload</function> example + + +]]> + + +
+ +
+ Overloadable Method calls and Property accesses + + Both method calls and property accesses can be overloaded via the + __call, __get and + __set methods. + + + + <function>__get</function> and + <function>__set</function> + + + 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); +?> +]]> + + + + <function>__get</function> example + +x; + } +} + +$foo = new Caller(); +$a = $foo->test(1, "2", 3.4, true); +var_dump($a); +?> +]]> + + +
+ +
+ Iteration + + Objects may be iterated in an overloaded way when used with foreach. The + default behavior is to iterate over all properties. + + + Object iteration example + + $prop_value) { + // using the property +} +?> +]]> + + + + Each class whose instances can be iterated with foreach should implement + the empty interface Traversable. Hence any object that + says it implements Traversable can be used with foreach. + + + The interfaces IteratorAggregate and Iterator + allows you to specify how class objects are iterated in &php; code. The first + of them simply has a method getIterator which must + return an array or an object that either implements the interface + Iterator or is instantiated from an internal + class that can be iterated + + + Iterator creation example + +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->hasMore(); $it->next) { + $key = $it->current(); + $val = $it->key(); + echo "$key = $val\n"; +} +unset($it); +?> +]]> + + +
+ +
+ <literal>__METHOD__</literal> constant + + The new __METHOD__ pseudo constant shows the current + class and method when used inside a method and the function when used outside + of a class. + + + <literal>__METHOD__</literal> use example + + +]]> + + +
+ +
+ <function>__toString</function> method + + The new __toString magic method allows you to + overload the object to string conversion. + + + <function>__toString</function> example + + +]]> + + +
+ +
+ Reflection API + + &php; 5 comes with a complete reflection API that adds the ability to + reverse-engineer classes, interfaces, functions and methods as well as + extensions. + + + The reflection API also offers ways of getting doc comments for + functions, classes and methods. + + + Nearly all aspects of object oriented code can be reflected by using the + reflection API which is + + documented separately. + + + Reflection API use example + + +]]> + + +
+
+