summaryrefslogtreecommitdiff
path: root/Zend/ZEND_CHANGES
diff options
context:
space:
mode:
authorSebastian Bergmann <sebastian@php.net>2001-12-29 09:21:54 +0000
committerSebastian Bergmann <sebastian@php.net>2001-12-29 09:21:54 +0000
commit1d4793e5e82f5617c6bbd42e1cbfc0e97dbe0718 (patch)
tree169b996281f85d9979e708654ee5058f698d454f /Zend/ZEND_CHANGES
parent76cfd48f729d71d4eea2ca897ea19b3e97c015e4 (diff)
downloadphp-git-1d4793e5e82f5617c6bbd42e1cbfc0e97dbe0718.tar.gz
Integrate Andi's examples and some notes by Stig.
Diffstat (limited to 'Zend/ZEND_CHANGES')
-rw-r--r--Zend/ZEND_CHANGES381
1 files changed, 323 insertions, 58 deletions
diff --git a/Zend/ZEND_CHANGES b/Zend/ZEND_CHANGES
index 5f399ba4ec..091e8f0718 100644
--- a/Zend/ZEND_CHANGES
+++ b/Zend/ZEND_CHANGES
@@ -1,6 +1,6 @@
Changes in the Zend Engine 2.0
- * New object model.
+ * 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
@@ -21,63 +21,93 @@ Changes in the Zend Engine 2.0
To simplify migration, the Zend Engine 2.0 supports an optional
'auto-clone' feature, which performs a cloning of the object
- whenever it would have been copied in version 1.0. Optionally,
- it emits an E_NOTICE message whenever such an automatic clone
- occurs, in order to allow developers to gradually migrate to the
- version 2.0-style behavior (without automatic clones).
+ whenever it would have been copied in the Zend Engine 1.0.
+ Optionally, it emits an E_NOTICE message whenever such an
+ automatic clone occurs, in order to allow developers to
+ gradually migrate to the behavior of the Zend Engine 2 (without
+ automatic clones).
+
+ * 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:
- * delete statement.
+ <?php
+ $copy_of_object = $object->__clone();
+ ?>
- The Zend Engine 1.0 had no means to force deletion of an object
- if there are still references to it. The newly introduced delete
- statement calls the object’s destructor and frees it even if the
- object is referenced by some other places in the engine. Other
- references to the deleted object become stale and trying to
- access them results in a fatal error.
+ 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.
- Note that if you have a user-defined function delete() in an old
- script, this script will yield a parser error with the Zend
- Engine 2.0, since 'delete' is now a reserved word.
+ Example:
- * Exceptions.
+ <?php
+ class MyCloneable {
+ static $id = 0;
- 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.
+ function MyCloneable() {
+ $this->id = self::$id++;
+ }
- Example
+ function __clone() {
+ $this->name = $clone->name;
+ $this->address = "New York";
+ $this->id = self::$id++;
+ }
+ }
- <?php
- class MyException {
- function MyException($_error) {
- $this->error = $_error;
- }
+ $obj = new MyCloneable();
- function getException() {
- return $this->error;
- }
- }
+ $obj->name = "Hello";
+ $obj->address = "Tel-Aviv";
- function ThrowException() {
- throw new MyException("'This is an exception!'");
- }
+ print $obj->id . "\n";
- try {
- } catch ($exception) {
- print "There was an exception: " . $exception->getException();
- print "\n";
- }
+ $obj = $obj->__clone();
- try {
- ThrowException();
- } catch ($exception) {
- print "There was an exception: " . $exception->getException();
- print "\n";
- }
- ?>
+ print $obj->id . "\n";
+ print $obj->name . "\n";
+ print $obj->address . "\n";
+ ?>
- Old code that does not define user-space functions 'catch',
- 'throw' and 'try' will run without modifications.
+ * Forced deletion of objects.
+
+ The Zend Engine 1.0 had no means to force deletion of an object
+ if there are still references to it. The newly introduced delete
+ statement calls the object's destructor and frees it even if the
+ object is referenced by some other places in the engine. Other
+ references to the deleted object become stale and trying to
+ access them results in a fatal error.
+
+ Note that if you have a user-defined function delete() in an old
+ script, this script will yield a parser error with the Zend
+ Engine 2.0, since 'delete' is now a reserved word.
* Namespaces.
@@ -99,30 +129,265 @@ Changes in the Zend Engine 2.0
operator. It is possible to "import" symbols from one namespace
into another.
+ Namespaces and classes are the same with the Zend Engine 2.0,
+ except that you can't instantiate a namespace with "new". This
+ essentially also makes a class a namespace, so the scoping rules
+ for namespaces apply for classes. Some of the consequences of
+ this are:
+
+ * Classes may contain classes.
+
+ Example:
+
+ <?php
+ class DB::MySQL {
+ var $host = "";
+
+ function db_connect($user) {
+ print "Connecting to MySQL database '$this->host' as $user\n";
+ }
+ }
+
+ class DB::Oracle {
+ var $host = "localhost";
+
+ function db_connect($user) {
+ print "Connecting to Oracle database '$this->host' as $user\n";
+ }
+ }
+
+ $MySQL_obj = new DB::MySQL();
+ $MySQL_obj->db_connect("Susan");
+
+ $Oracle_obj = new DB::Oracle();
+ $Oracle_obj->db_connect("Barbara");
+ ?>
+
+ * Classes may contain constants.
+
+ Example:
+
+ <?php
+ class foo {
+ const hey = "hello";
+ }
+
+ print foo::hey;
+ ?>
+
+ * Current namespace's symbol tables are searched first for
+ constants and functions.
+
+ Example:
+
+ The following code prints "foobar", not "foo", because
+ the class constant overrides the "global" constant of
+ the same name.
+
+ <?php
+ define("foo", "bar");
+
+ class FooClass {
+ const foo = "foobar";
+
+ function printFoo() {
+ print foo;
+ }
+ }
+ ?>
+
+ * In the scope of a function, the current namespace is that
+ of the containing class/namespace.
+
+ Example:
+
+ <?php
+ class FooClass {
+ function foo() {
+ $this->bar();
+ bar();
+ }
+
+ function bar() {
+ print "foobar\n";
+ }
+ }
+
+ $obj = new FooClass;
+ $obj->foo();
+ $obj->foo();
+ ?>
+
+ This prints "foobar" two times, since a bar() method exists
+ in the current namespace.
+
Old code that does not take advantage of namespaces will run
without modifications.
- * Static member variables of static classes can now be
- initialized.
+ * 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 foo
- {
- static $my_static = 5;
+ class BaseClass {
+ function __construct() {
+ print "In BaseClass constructor\n";
}
+ }
- print foo::$my_static;
+ class SubClass extends BaseClass {
+ function __construct() {
+ parent::__construct();
+ print "In SubClass constructor\n";
+ }
+ }
+
+ $obj = new BaseClass();
+ $obj = new SubClass();
?>
- * Class constants.
+ 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 foo
- {
- const hey = "hello";
+ class MyDestructableClass {
+ function __construct() {
+ print "In constructor\n";
+ $this->name = "MyDestructableClass";
+ }
+
+ function __destruct() {
+ print "Destroying " . $this->name . "\n";
+ }
}
-
- print foo::hey;
+
+ $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.
+
+ * 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.
+
+ Example:
+
+ <?php
+ class MyException {
+ function MyException($_error) {
+ $this->error = $_error;
+ }
+
+ function getException() {
+ return $this->error;
+ }
+ }
+
+ function ThrowException() {
+ throw new MyException("'This is an exception!'");
+ }
+
+ try {
+ } catch ($exception) {
+ print "There was an exception: " . $exception->getException();
+ print "\n";
+ }
+
+ try {
+ ThrowException();
+ } catch ($exception) {
+ print "There was an exception: " . $exception->getException();
+ print "\n";
+ }
+ ?>
+
+ Old code that has no user-defined functions 'catch', 'throw' and
+ 'try' will run without modifications.
+
+ * Derefencing 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();
+ ?>
+
+ * Static member variables of static classes can now be
+ initialized.
+
+ Example:
+
+ <?php
+ class foo {
+ static $my_static = 5;
+ }
+
+ print foo::$my_static;
?>
Changes in the Zend Engine 1.0