summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2017-01-30 22:28:45 +0100
committerNikita Popov <nikita.ppv@gmail.com>2017-01-30 22:50:25 +0100
commitdf404eccb57b58fdcfada0a2424904fac38a2ec4 (patch)
treedc848fa79475bf5079fac3795900a8908b25aab1
parent22ca84550afc0c7609f3496207209d38e1b54246 (diff)
downloadphp-git-df404eccb57b58fdcfada0a2424904fac38a2ec4.tar.gz
Remove ZEND_CHANGES and README.namespaces
-rw-r--r--README.namespaces174
-rw-r--r--Zend/ZEND_CHANGES1166
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.