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 objects' 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. To simplify migration, the Zend Engine 2.0 supports an optional 'auto-clone' feature, which performs a cloning of the object whenever it would have been copied in version 1.0. Optionally, it emits an E_NOTICE message whenever such an automatic clone occurs, in order to allow developers to gradually migrate to the version 2.0-style behavior (without automatic clones). * delete statement. The Zend Engine 1.0 had no means to force deletion of an object if there are still references to it. The newly introduces delete statement calls the object’s destructor and frees it even if the object is referenced by some other places in the engine. Other references to the deleted object become stale and trying to access them results in a fatal error. Note that if you have a user-defined function delete() in an old script, this script will yield a parser error with the Zend Engine 2.0, since 'delete' is now a reserved word. * Exceptions. The Zend Engine 1.0 had no exception handling. The Zend Engine 2.0 introduces a exception model similar to that of other programming languages. Example try { code if (failure) { throw new MyException(Failure); } code } catch ($exception) { handle exception throw $exception; // Re-throw exception. } Old code that does not use exceptions will run without modifications. * Namespaces. The Zend Engine 1.0 provided only three scopes: the global scope, the class scope and the function scope. All scopes but classes could contain variables, only the class and global scopes could contain functions, while only the global scope could contain constants and classes. This means that all of the Zend Engine 1.0's scoping methods were inherently limited for solving symbol name collision problems. The Zend Engine 2.0 introduces the concept of namespaces to manage the symbol collision problem by making it possible to define multiple symbol tables able to contain all types of symbols. The Zend Engine is aware of a current namespace, defaulting to the current global one. The current namespace may be changed on a file-by-file basis. Symbols in other namespaces than the current one may be referenced using a new namespace operator. It is possible to "import" symbols from one namespace into another. Old code that does not take advantage of namespaces will run without modifications. * Static member variables of static classes can now be initialized. * Class constants. 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.