diff options
Diffstat (limited to 'Zend/ZEND_CHANGES')
| -rw-r--r-- | Zend/ZEND_CHANGES | 1166 |
1 files changed, 1166 insertions, 0 deletions
diff --git a/Zend/ZEND_CHANGES b/Zend/ZEND_CHANGES new file mode 100644 index 0000000..5208ce1 --- /dev/null +++ b/Zend/ZEND_CHANGES @@ -0,0 +1,1166 @@ +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 + 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 + 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 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. |
