diff options
Diffstat (limited to 'Zend/ZEND_CHANGES')
-rw-r--r-- | Zend/ZEND_CHANGES | 1070 |
1 files changed, 0 insertions, 1070 deletions
diff --git a/Zend/ZEND_CHANGES b/Zend/ZEND_CHANGES deleted file mode 100644 index 85c7c5203e..0000000000 --- a/Zend/ZEND_CHANGES +++ /dev/null @@ -1,1070 +0,0 @@ -Changes in the Zend Engine 2.0 - - * New Object Model. - - The Zend Engine's handling of objects has been completely - changed in order to allow for new features, but also to increase - its performance. - - Objects were handled in previous versions like primitive types - (for instance integers and strings). The drawback of this method - is, that semantically the whole object was copied when a - variable was assigned or parameters were passed to a method. The - new approach refers to objects by handle and not by value (one - can think of a handle as an object's ID). - - Many PHP programmers aren't even aware of the copying quirks of - the old object model and, therefore, there is a relatively good - chance that the amount of PHP applications that will work out of - the box or after a very small amount of modifications would be - high. - - * $this - - Unlike in Zend Engine 1 the pseudo variable $this cannot be - exchanged in Zend Engine 2. You can of course modify or work with - an object by using $this but you cannot replace $this with another - object to change the original object. - - Example: - - <?php - class Foo { - function replace($other) - { - $this = $other; - } - } - - $object = new Foo; - $object->prop = 'Hello'; - - $other = new Foo; - $other->prop = 'Bye'; - - $object->replace($other); - - print $object->prop; // still shows 'Hello' - - ?> - - * Private and Protected Members. - - The Zend Engine 2.0 introduces private and protected member - variables. Note that for performance reasons no error message is - emitted in case of an illegal access to a private or protectecd - member variable. - - Example: - - <?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(); - ?> - - 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. - - * Private and protected methods. - - The Zend Engine 2.0 introduces private and protected methods. - - Example: - - <?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(); - ?> - - Old code that has no user-defined classes or functions named - 'public', 'protected' or 'private' should run without modifications. - - * Abstract Classes and Methods. - - The Zend Engine 2.0 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. - - Example: - - <?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(); - ?> - - Classes that do not have abstract methods can be declared abstract - to prevent them from being instantiated. - - Old code that has no user-defined classes or functions named - 'abstract' should run without modifications. - - * Interfaces. - - The Zend Engine 2.0 introduces interfaces. A class may implement - an arbitrary list of interfaces. - - Example: - - <?php - interface Printable { - public function dump(); - } - - class PrintableExample implements Printable { - public function dump() { - // ... - } - } - ?> - - 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 the Zend Engine 2.0 introduces the - ability to use class type hints to declare the expected class of - objects that are passed as parameters to a method. - - Example: - - <?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); - ?> - - These class type hints are not checked upon compilation, as would - be the case in a typed language, but during runtime. - - This means that - - function foo(ClassName $object) { - // ... - } - - is equivalent to - - function foo($object) { - if (!($object instanceof ClassName)) { - die('Argument 1 must be an instance of ClassName'); - } - } - - This syntax only applies to objects/classes, not built-in types. - - * Final methods and classes. - - The Zend Engine 2.0 introduces the "final" keyword to declare - final members and methods. Those cannot be overridden by - sub-classes. - - Example: - - <?php - class Foo { - final function bar() { - // ... - } - } - ?> - - 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. - - Example: - - <?php - final class Foo { - // class definition - } - // the next line is impossible - // class Bork extends Foo {} - ?> - - Properties cannot be final. - - Old code that has no user-defined classes or functions named - 'final' should run without modifications. - - * Object Cloning. - - The Zend Engine 1.0 offered no way a user could decide what copy - constructor to run when an object is duplicated. During - duplication, the Zend Engine 1.0 did a bitwise 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 calling the object's __clone() - method. - - Example: - - <?php - $copy_of_object = $object->__clone(); - ?> - - When the developer asks to create a new copy of an object, the - Zend Engine 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. [The function hasn't been implemented yet] - - Example: - - <?php - class MyCloneable { - static $id = 0; - - function MyCloneable() { - $this->id = self::$id++; - } - - function __clone() { - $this->name = $that->name; - $this->address = 'New York'; - $this->id = self::$id++; - } - } - - $obj = new MyCloneable(); - - $obj->name = 'Hello'; - $obj->address = 'Tel-Aviv'; - - print $obj->id . "\n"; - - $obj = $obj->__clone(); - - print $obj->id . "\n"; - print $obj->name . "\n"; - print $obj->address . "\n"; - ?> - - * Unified Constructors. - - The Zend Engine 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 can be used. - - With the Zend Engine 1.0, 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 - the Zend Engine 1.0 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. - - The Zend Engine 2.0 introduces a standard way of declaring - constructor methods by calling them by the name __construct(). - - Example: - - <?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(); - ?> - - For backwards compatibility, if the Zend Engine 2.0 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 the Zend Engine - 1.0, although PHP had already support for registering functions - which should be run on request shutdown. - - The Zend Engine 2.0 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 name __destruct() that - recieves no parameters, is called before the object is freed - from memory. - - Example: - - <?php - class MyDestructableClass { - function __construct() { - print "In constructor\n"; - $this->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. - - The Zend Engine 2.0 introduces per-class constants. - - Example: - - <?php - class Foo { - const constant = 'constant'; - } - - echo 'Foo::constant = ' . Foo::constant . "\n"; - ?> - - Old code that has no user-defined classes or functions - named 'const' will run without modifications. - - * Exceptions. - - The Zend Engine 1.0 had no exception handling. The Zend Engine 2.0 - introduces a exception model similar to that of other programming - languages. But there is no catch all and no finally clause. - - Old code that has no user-defined classes or functions 'catch', - 'throw' and 'try' will run without modifications. - - Exceptions can be rethrown in catch blocks. Also it is possible to - have multiple catch blocks. In that case the caught exception is - compare with the classtype of each catch block from top to bottom - and the first block that has a 'instanceof' match gets executed. - When the catch block finishes execution continues at the end of - the last catch block. If no catch block has a '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. - - Example: - - <?php - class MyException { - function __construct($exception) { - $this->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 proerty and hence there getter methods. As the code - shows it is possible to read any available information by using the - getter methods. But since some og 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. - - Emulating class Exception: - - <?php - class Exception { - function __construct(string $message=NULL, int code=0) { - if (func_num_args()) { - $this->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 builtin handler for - uncaught exceptions. - - * Dereferencing objects returned from functions. - - Example: - - <?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(); - ?> - - * Member variables of classes can now be initialized. - - Example: - - <?php - class foo { - static $my_static = 5; - public $my_prop = 'bla'; - } - - print foo::$my_static; - - $obj = foo; - - print $obj->my_prop; - ?> - - * Static Methods. - - The Zend Engine 2.0 introduces the 'static' keyword to declare - a method static, thus callable from outside the object context. - - Example: - - <?php - class Foo { - public static function aStaticMethod() { - // ... - } - } - - Foo::aStaticMethod(); - ?> - - The pseudo variable $this is not available inside a method that - has been declared static. - - * instanceof. - New support for an instanceof operator which checks if an object - is of a certain class or interface type. - - Example: - - <?php - - class Foo { - } - - $obj = new Foo(); - if ($obj instanceof Foo) { - print "Yay!\n"; - } - ?> - - * 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 that are passed by reference to a function - may now have default values. - - Example: - - <?php - function my_function(&$var = null) { - if ($var === null) { - die('$var needs to have a value'); - } - } - ?> - - * __autoload(). - - 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. __autoload() must succeed in loading the class. If it - doesn't then an E_ERROR is emitted. - - Example: - - <?php - function __autoload($className) { - include_once $className . '.php'; - } - - $object = new ClassName; - ?> - - * Method calls and property accesses can be overloaded - by class methods __call(), __get() and __set(). - - __get() and __set() Example: - - <?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); - ?> - - __call() Example: - - <?php - class Caller { - var $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); - ?> - - * Iteration - - Objects may be iterated in an overloaded way when used with - foreach. The default behavior is to iterate over all properties - with respect to property visibility. - - Example: - - <?php - class Foo { - var $x = 1; - var $y = 2; - } - - $obj = new Foo; - - foreach ($obj as $prp_name => $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' allow to specify - how class objects are iterated in PHP code. The first of them simply - has a method 'getIterator' which must return an object that either - implements the interface 'Iterator' or is instantiated from an - internal class that can be iterated. - - Example: - - <?php - class ObjectIterator implements Iterator { - - private $obj; - private $num; - - function __construct($obj) { - $this->obj = $obj; - } - function rewind() { - $this->num = 0; - } - function hasMore() { - 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); - ?> - - The matching for directive is very intersting here since it shows - the use of all abstract methods declared in the interfaces Iterator - and IteratorAggregate respectively. - - * __METHOD__ - - The pseudo constant __METHOD__ shows the current class and method - when used inside a method and the function when used outside of a - class. - - Example: - - <?php - class Foo { - function Show() { - echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__; - } - } - function Test() { - echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__; - } - ?> - - * __toString() - - The magic method __toString() allows to overload the object to - string conversion. This conversion is only done automatically for - printing functions (echo, *printf) but not for other functions - that expect strings. Also the function __toString is not used in - places where objects are not allowed but strings are like array - indices. Note that specialized objects maybe converted to a string - in any place but without calling __toString(). - - Example: - - <?php - class Foo { - function __toString() { - return "What ever"; - } - - $obj = Foo; - - $str = (string) $obj; // call __toString() - - echo $obj; // call __toString() - - $ar = array(); - $ar[(string)$obj]; // this works - $ar[$obj]; // this is not allowed - ?> - - * Reflection API - - PHP5 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 separatley: - http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html - - Example: - - <?php - class Foo { - public $prop; - function Func($name) { - echo "Hello $name"; - } - - reflection_class::export('Foo'); - reflection_object::export(new Foo); - reflection_method::export('Foo', 'func'); - reflection_property::export('Foo', 'prop'); - reflection_extension::export('standard'); - ?> - - * New memory manager - The Zend Engine has a new memory manager which allows it to run efficiently - in multi-threaded environments as it doesn't need to use mutexes to lock - and unlock during allocation/deallocation. - - * Others - Probably other changes which we forgot to list. This list will be kept up-to-date - as much as possible. - - -Changes in the Zend Engine 1.0 - - The Zend Engine was designed from the ground up for increased speed, - reduced memory consumption and more reliable execution. We dare say - it meets all of these goals and does so pretty well. Beyond that, - there are several improvements in the language engine features: - - * References support. - - $foo = &$a; would make $foo and $a be two names to the same - variable. This works with arrays as well, on either side; e.g., - $foo = &$a[7]; would make $foo and $a[7] be two names to the - same variable. Changing one would change the other and vice - versa. - - * Object overloading support. - - This feature allows various OO libraries to use the OO notation - of PHP to access their functionality. Right now, no use is made - of that feature, but we'd have a COM module ready by the time - PHP 4.0 is released. A CORBA module would probably follow. - - * include() and eval() are now functions, and not statements. - - That means they return a value. The default return value from - include() and eval() is 1, so that you can do if (include()) - without further coding. The return value may be changed by - returning a value from the global scope of the included file or - the evaluated string. For example, if 'return 7;' is executed in - the global scope of foo.inc, include('foo.inc') would evaluate - to 7. - - * Automatic resource deallocation. - - Several people have been bitten by the fact that PHP 3.0 had no - concept of reference counting. The Zend Engine adds full - reference counting for every value in the system, including - resources. As soon as a resource is no longer referenced from - any variable, it is automatically destroyed to save memory and - resources. The most obvious example for the advantage in this is - a loop that has an SQL query inside it, something like '$result - = sql_query(...);'. In PHP 3.0, every iteration resulted in - another SQL result-set allocated in the memory, and all of the - result sets weren't destroyed until the end of the script's - execution. With the Zend Engine, as soon as we overwrite an old - result set with a new one, the old result set which is no longer - referenced, is destroyed. - - * Full support for nesting arrays and objects within each other, - in as many levels as you want. - - * true and false are now constants of type boolean. - - Comparing any other value to them would convert that value to a - boolean first, and conduct the comparison later. That means, for - example, that 5==true would evaluate to true (in PHP 3.0, true - was nothing but a constant for the integer value of 1, so - 5==true was identical to 5==1, which was false). - - * Runtime binding of function names. - - This complex name has a simple explanation - you can now call - functions before they're declared! - - * Added here-docs support. - - * Added foreach. - - Two syntaxes supported: - - foreach(array_expr as $val) statement - foreach(array_expr as $key => $val) statement - - * A true unset() implementation. - - A variable or element that is unset(), is now sent to oblivion - in its entirely, no trace remains from it. - - * Output buffering support. - - Use ob_start() to begin output buffering, ob_end_flush() to end - buffering and send out the buffered contents, ob_end_clean() to - end buffering without sending the buffered contents, and - ob_get_contents() to retreive the current contents of the output - buffer. Header information (header(), content type, cookies) are - not buffered. By turning on output buffering, you can - effectively send header information all throughout your file, - regardless of whether you've emitted body output or not. - - * Full variable reference within quoted strings: - - ${expr} - full indirect reference support for scalar - variables - {variable} - full variable support - - For example: - - $foo[5]['bar'] = 'foobar'; - print "{$foo[5]["bar"]}"; // would print "foobar" - - * Ability to call member functions of other classes from within - member functions or from the global scope. - - You can now, for example, override a parent function with a - child function, and call the parent function from it. - - * Runtime information for classes (class name, parent, available - functions, etc.). - - * Much more efficient syntax highlighter - runs much quicker, - performs more reliably, and generates much tighter HTML. - - * A full-featured debugger has been integrated with the language - (supports breakpoints, expression evaluation, step-in/over, - function call backtrace, and more). - - The Zend Engine claims 100% compatability with the engine of PHP - 3.0, and is shamelessly lying about it. Here's why: - - * Static variable initializers only accept scalar values - (in PHP 3.0 they accepted any valid expression). The impact - should be somewhere in between void and non existent, since - initializing a static variable with anything but a simple - static value makes no sense at all. - - * The scope of break and continue is local to that of an - include()'d file or an eval()'d string. The impact should - be somewhat smaller of the one above. - - * The return statement no longer works from a require()'d file. It - hardly worked in PHP 3.0, so the impact should be fairly small. If - you want this functionality - use include() instead. - - * unset() is no longer a function, but a statement. - - * The following letter combination is not supported within - encapsulated strings: "{$". If you have a string that includes - this letter combination, for example, print "{$somevar"; (which - printed the letter { and the contents of the variable $somevar in - PHP 3.0), it will result in a parse error with the Zend Engine. - In this case, you would have to change the code to print - "\{$somevar"; This incompatability is due to the full variable - reference within quoted strings feature added in the Zend - Engine. |