2001-09-23 01:03:05 +08:00
|
|
|
|
Changes in the Zend Engine 2.0
|
2000-11-13 01:21:14 +08:00
|
|
|
|
|
2001-09-23 01:03:05 +08:00
|
|
|
|
* 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<63>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.
|
|
|
|
|
|
|
|
|
|
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.
|