diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2017-01-30 22:28:45 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2017-01-30 22:50:25 +0100 |
commit | df404eccb57b58fdcfada0a2424904fac38a2ec4 (patch) | |
tree | dc848fa79475bf5079fac3795900a8908b25aab1 | |
parent | 22ca84550afc0c7609f3496207209d38e1b54246 (diff) | |
download | php-git-df404eccb57b58fdcfada0a2424904fac38a2ec4.tar.gz |
Remove ZEND_CHANGES and README.namespaces
-rw-r--r-- | README.namespaces | 174 | ||||
-rw-r--r-- | Zend/ZEND_CHANGES | 1166 |
2 files changed, 0 insertions, 1340 deletions
diff --git a/README.namespaces b/README.namespaces deleted file mode 100644 index 9c427b634f..0000000000 --- a/README.namespaces +++ /dev/null @@ -1,174 +0,0 @@ -Design -====== - -Main assumption of the model is that the problem that we are to solve is the -problem of the very long class names in PHP libraries. We would not attempt -to take autoloader's job or create packaging model - only make names -manageable. - -Namespaces are defined the following way: - -Zend/DB/Connection.php: -<?php -namespace Zend\DB; - -class Connection { -} - -function connect() { -} -?> - -Namespace definition does the following: -All class and function names inside are automatically prefixed with -namespace name. Inside namespace, local name always takes precedence over -global name. Several files may be using the same namespace. -The namespace declaration statement must be the very first statement in -the file. The only exception is "declare" statement that can be used before. - -Every class and function in a namespace can be referred to by the full name -- e.g. Zend\DB\Connection or Zend\DB\connect - at any time. - -<?php -require 'Zend/Db/Connection.php'; -$x = new Zend\DB\Connection; -Zend\DB\connect(); -?> - -Namespace or class name can be imported: - -<?php -require 'Zend/Db/Connection.php'; -use Zend\DB; -use Zend\DB\Connection as DbConnection; - -$x = new Zend\DB\Connection(); -$y = new DB\connection(); -$z = new DbConnection(); -DB\connect(); -?> - -The use statement only defines name aliasing. It may create name alias for -namespace or class. The simple form of statement "use A\B\C\D;" is -equivalent to "use A\B\C\D as D;". The use statement can be used at any -time in the global scope (not inside function/class) and takes effect from -the point of definition down to the end of file. It is recommended however to -place the use statements at the beginning of the file. The use statements have -effect only on the file where they appear. - -The special "empty" namespace (\ prefix) is useful as explicit global -namespace qualification. All class and function names started from \ -interpreted as global. - -<?php -namespace A\B\C; - -$con = \mysql_connect(...); -?> - -A special constant __NAMESPACE__ contains the name of the current namespace. -It can be used to construct fully-qualified names to pass them as callbacks. - -<?php -namespace A\B\C; - -function foo() { -} - -set_error_handler(__NAMESPACE__ . "\foo"); -?> - -In global namespace __NAMESPACE__ constant has the value of empty string. - -Names inside namespace are resolved according to the following rules: - -1) all qualified names are translated during compilation according to -current import rules. So if we have "use A\B\C" and then "C\D\e()" -it is translated to "A\B\C\D\e()". -2) unqualified class names translated during compilation according to -current import rules. So if we have "use A\B\C" and then "new C()" it -is translated to "new A\B\C()". -3) inside namespace, calls to unqualified functions that are defined in -current namespace (and are known at the time the call is parsed) are -interpreted as calls to these namespace functions. -4) inside namespace, calls to unqualified functions that are not defined -in current namespace are resolved at run-time. The call to function foo() -inside namespace (A\B) first tries to find and call function from current -namespace A\B\foo() and if it doesn't exist PHP tries to call internal -function foo(). Note that using foo() inside namespace you can call only -internal PHP functions, however using \foo() you are able to call any -function from the global namespace. -5) unqualified class names are resolved at run-time. E.q. "new Exception()" -first tries to use (and autoload) class from current namespace and in case -of failure uses internal PHP class. Note that using "new A" in namespace -you can only create class from this namespace or internal PHP class, however -using "new \A" you are able to create any class from the global namespace. -6) Calls to qualified functions are resolved at run-time. Call to -A\B\foo() first tries to call function foo() from namespace A\B, then -it tries to find class A\B (__autoload() it if necessary) and call its -static method foo() -7) qualified class names are interpreted as class from corresponding -namespace. So "new A\B\C()" refers to class C from namespace A\B. - -Examples --------- -<?php -namespace A; -foo(); // first tries to call "foo" defined in namespace "A" - // then calls internal function "foo" -\foo(); // calls function "foo" defined in global scope -?> - -<?php -namespace A; -new B(); // first tries to create object of class "B" defined in namespace "A" - // then creates object of internal class "B" -new \B(); // creates object of class "B" defined in global scope -?> - -<?php -namespace A; -new A(); // first tries to create object of class "A" from namespace "A" (A\A) - // then creates object of internal class "A" -?> - -<?php -namespace A; -B\foo(); // first tries to call function "foo" from namespace "A\B" - // then calls method "foo" of internal class "B" -\B\foo(); // first tries to call function "foo" from namespace "B" - // then calls method "foo" of class "B" from global scope -?> - -The worst case if class name conflicts with namespace name -<?php -namespace A; -A\foo(); // first tries to call function "foo" from namespace "A\A" - // then tries to call method "foo" of class "A" from namespace "A" - // then tries to call function "foo" from namespace "A" - // then calls method "foo" of internal class "A" -\A\foo(); // first tries to call function "foo" from namespace "A" - // then calls method "foo" of class "A" from global scope -?> - -TODO -==== - -* Support for namespace constants? - -* performance problems - - calls to internal functions in namespaces are slower, because PHP first - looks for such function in current namespace - - calls to static methods are slower, because PHP first tries to look - for corresponding function in namespace - -* Extend the Reflection API? - * Add ReflectionNamespace class - + getName() - + getClasses() - + getFunctions() - + getFiles() - * Add getNamespace() methods to ReflectionClass and ReflectionFunction - -* Rename namespaces to packages? - diff --git a/Zend/ZEND_CHANGES b/Zend/ZEND_CHANGES deleted file mode 100644 index 94e164c290..0000000000 --- a/Zend/ZEND_CHANGES +++ /dev/null @@ -1,1166 +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' - - ?> - - Zend Engine 2.0 will issue a compile error, if an assignment - to $this is found. - - * 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. - - An interface may extend one or more base interfaces (but not - implement them). Neither a class nor an interface can inherit - methods of the same name from different root interfaces. - - Interfaces may contain abstract static methods. - - Example: - - <?php - interface Printable { - function dump(); - } - - interface Streamable extends Printable { - function writeToStream(); - static function readFromStream(); - } - - class PrintableExample implements Streamable { - public function dump() { - // ... - } - function writeToStream() { - // ... - } - static function readFromStream() { - // ... - } - } - ?> - - A class that does not implement all interface methods must be - declared as an abstract class. - - * 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 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. See per-class constants below. - - 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 using the clone operator. - - Example: - - <?php - $copy_of_object = clone $object; - ?> - - 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 - ensures, that the clone will be initialized with all of the - properties from the source object, so that developers can start - with a by-value replica of the source object, and only override - properties that need to be changed. - - Example: - <?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'; - - $obj_clone = clone $obj; - - print $obj->id . "\n"; - print $obj->name . "\n"; - print $obj->address . "\n"; - - print $obj_clone->id . "\n"; - print $obj_clone->name . "\n"; - print $obj_clone->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 - receives 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 - compared 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 property. 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. - - 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. - - Note: The method getMessage() is a final read only access method to - the private proeprty message that is set in the constructor. If you - feel a need to overwrite the exception display then overload method - __toString() in your derived class or implement your own extneral - exception display function to accomplish your desired formatting. - - Example: - - <?php - function display_exception(Exception $ex) - { - echo 'Exception: ' . $ex->getMessage() . 'with backtrace: <pre>'; - echo $ex->getTrace(); - echo '</pre>'; - } - - try - { - // your code here - } - catch (Exception $ex) - { - display_exeption($ex); - } - ?> - - * 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"; - } - ?> - - * 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 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->key(); - $val = $it->current(); - 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. - - * Array overloading - - Objects can be used with Array notation when they implement the - interface ArrayAccess. You cannot use such objects in standard - array functions, however you have full control over the array - notation. This allows lazy initialization or read only array. - - Note that setting [] results in a call to offsetSet() with - index being NULL. That means that as with standard arrays you - cannot store NULL keys. - - Example: - - <?php - class ArrayClass implements ArrayAccess { - public $a = array(); - - function offsetExists($index) { - return array_key_exists($index, $this->a); - } - function offsetGet($index) { - return $this->a[$index]; - } - function offsetSet($index, $newval) { - return $this->a[$index] = $newval; - } - function offsetUnset($index) { - unset($this->a[$index]); - } - } - - $obj = new ArrayClass; - - $obj[0] = 'bla'; // calls offsetSet(0,'bla') - $obj[] = 42; // calls offsetSet(NULL, 42) - $x = $obj[0]; // calls offsetGet(0) - $b = isset($obj[0]); // calls offsetExists(0) - unset($obj[0]); // calls offsetUnset(0) - ?> - - - * __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 - the printing functions (echo, print) 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 may be converted to a string - in any place but without calling __toString(). - - Example: - - <?php - class Foo { - function __toString() { - return "What ever"; - } - } - - $obj = new 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 - - 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: - http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html - - Example: - - <?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'); - ?> - - * 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 retrieve 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% compatibility 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 incompatibility is due to the full variable - reference within quoted strings feature added in the Zend - Engine. |