Preface
Today I suddenly thought of the official PHP website and saw the announcement of PHP5 launch at a glance. Although I have seen the preview of PHP5 before, I still carefully read the article about the new features of PHP 5/Zend Engine 2.0, and a JAVA breath hits me...
This article was specially translated and published on the CSDN website for readers.
New features of PHP 5/Zend Engine 2.0
Xu Huanchun translated sfwebsite@
/
A brand new object model
The object processing part in PHP has been completely rewritten, with better performance and more features. In previous versions of PHP, objects were treated the same as built-in variable types (such as integer and string). The disadvantage is that when the variable is assigned a value as an object or passed as a parameter, the object copy is obtained. In the new version, the object is referenced through the handle, not through its value. (The handle can be considered an identifier of the object)
Many PHP programmers may not be aware of the "copy quirk" of previous object models, so previous PHP programs will not need to make any changes, or just make small changes to run.
Private and protect members
PHP 5 introduces private and protected member variables that define when class attributes can be accessed.
example
The class's protected member variable can be accessed in the extended class of the class, while the private member variable can only be accessed in this class.
<?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();
?>
Private and protection methods
In PHP 5 (ZEND Engine 2), private and protection methods are also introduced.
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();
?>
Although keywords such as "public,", "protected" or "private" were not defined in user-defined classes or methods in previous codes, they could run without editing.
Abstract classes and methods
PHP 5 also introduces abstract classes and methods. Abstract methods only declare method definitions and are not for actual operation. Classes containing abstract methods need to be declared as abstract classes.
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();
?>
Abstract classes cannot be instantiated. Although the "abstract" keyword was not defined in user-defined classes or methods in previous code, it can be run without editing.
interface
ZEND Engine 2.0 introduces interfaces. A class can run arbitrary interface list.
Example
example:
<?php
interface Throwable {
public function getMessage();
}
class Exception implements Throwable {
public function getMessage() {
// ...
}
?>
Although the "interface" keyword was not defined in user-defined classes or methods in previous code, it can be run without editing.
Class type definition
While retaining classes without defining types, PHP 5 introduces class type definitions to declare which class you want to pass to a method through parameters.
Example
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 definitions are not checked in compilation like some languages that require type predefined, but are performed at runtime. This means:
<?php
function foo(ClassName $object) {
// ...
}
?>
Equivalent to:
<?php
function foo($object) {
if (!($object instanceof ClassName)) {
die("Argument 1 must be an instance of ClassName");
}
}
?>
This syntax is only used for objects or classes and is not applicable to built-in types.
final
PHP 5 introduces the "final" keyword to define members or methods that cannot be overridden in subclasses.
example:
<?php
class Foo {
final function bar() {
// ...
}
}
?>
Although the "final" keyword was not defined in user-defined classes or methods in previous code, it can be run without editing.
Object cloning
PHP 4 When an object is copied, the user cannot decide on the copying mechanism. When copying, PHP 4 copies a copy that is exactly the same as the original object one by one.
We don't always have to build a exactly the same copy. A good example of needing a copy mechanism is when there is an object representing a GTK window that has all the resources of that window, and when you create a copy, you may need a new window that has all the properties of the original window, but needs the resources that have the new window. Another example is that you have an object that refers to another object. When you copy the parent object, you want to create a new instance of that reference object so that the copy can refer to it.
Copying an object is completed by calling the object's __clone() method:
<?php
$copy_of_object = $object->__clone();
?>
When the developer requests to create a new copy of an object, the ZEND engine checks whether the __clone() method is defined. If undefined, it calls a default __clone() method to copy all properties of the object. If the method is defined, the method is responsible for setting the necessary properties in the copy. For convenience, the engine will provide a function to import all properties from the source object, so that it can first get a copy of the source object with a value, and only need to overwrite the properties that need to be changed.
example:
<?php
class MyCloneable {
static $id = 0;
function MyCloneable() {
$this->id = self::$id++;
}
function __clone() {
$this->name = $that->name;
$this->address = "New York";
$this->id = self::$id++;
}
}
$obj = new MyCloneable();
$obj->name = "Hello";
$obj->address = "Tel-Aviv";
print $obj->id . "\n";
$obj = $obj->__clone();
print $obj->id . "\n";
print $obj->name . "\n";
print $obj->address . "\n";
?>
Unified constructor method name
The ZEND engine allows developers to define the constructor of a class. A class with a constructor will first call the constructor when created. The constructor is suitable for initialization before formally using the class.
In PHP4, the constructor's name is the same as the class name. Since the practice of calling parent classes in derived classes is quite common, it leads to a bit clumsy handling in PHP4 when classes move in a large class inheritance. When a derived class is moved to a different parent class, the constructor name of the parent class must be different. In this way, the statements in the derived class that call the parent class constructor need to be rewritten.
PHP 5 introduces a standard way of declaring constructor methods by calling them by the name __construct().
PHP5 introduces the method name __construct() to define the constructor.
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 backward compatibility, when PHP5 cannot find the __construct() method in the class, it will search for the constructor through the old method, that is, the class name. This means that the only possible compatibility issue is that a method name called __construct() has been used in previous code.
Destruction method
Defining a destructor method is very useful. The destructor method can record debugging information, close database connections, and do other finishing work. This mechanism is not available in PHP4, although PHP has supported registering functions that need to be run at the end of the request.
PHP 5 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.
PHP5 introduces a destructor similar to other object-oriented languages such as Java: When the last reference to the object is cleared, the system will call a destructor named __destruct() before the object is released 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();
?>
Similar to the constructor, the engine will not call the parent class's destructor. In order to call this method, you need to call it through the parent::__destruct() statement in the child class's destructor.
constant
PHP 5 introduces class constant definitions:
<?php
class Foo {
const constant = "constant";
}
echo "Foo::constant = " . Foo::constant . "\n";
?>
PHP5 allows expressions in constants, but expressions in constants will be calculated at compile time. Therefore, the constant cannot change its value during runtime.
<?php
class Bar {
const a = 1<<0;
const b = 1<<1;
const c = a | b;
}
?>
Although the "const" keyword was not defined in user-defined classes or methods in previous code, it can be run without editing.
exception
PHP 4 had no exception handling. PHP 5 introduces a exception model similar to that of other programming languages.
There are no exception processing in PHP4, and PHP5 references an exception processing model similar to other languages.
example:
<?php
class MyExceptionFoo extends Exception {
function __construct($exception) {
parent::__construct($exception);
}
}
try {
throw new MyExceptionFoo("Hello");
} catch (MyException $exception) {
print $exception->getMessage();
}
?>
Although the 'catch', 'throw' and 'try' keywords were not defined in user-defined classes or methods in previous code, they could run without editing.
Function returns object value
In PHP 4 it wasn't possible to dereference objects returned by functions and make further method calls on those objects. With the advent of Zend Engine 2, the following is now possible:
In PHP4, it is impossible for a function to return the value of an object and make a method call to the returned object. Through ZEND Engine 2, all this becomes possible:
<?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();
?>
Static member variables in static classes are now initialized
Example
<?php
class foo {
static $my_static = 5;
}
print foo::$my_static;
?>
Static method
PHP5 introduces the keyword 'static' to define a static method so that it can be called from outside the object.
example:
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
?>
The dummy variable $this is invalid in static methods.
instanceof
PHP5 introduces the keyword instanceof to determine whether an object is an instance of an object, or a derived object, or uses a certain interface.
example:
<?php
class baseClass { }
$a = new baseClass;
if ($a instanceof basicClass) {
echo "Hello World";
}
?>
Static function variables
All static variables are now processed at compile time, which allows developers to specify static variables by reference. This change improves efficiency but means that it is impossible to make indirect references to static variables.
Default value is allowed to be defined by parameters in the function by address transfer method
example:
<?php
function my_function(&$var = null) {
if ($var === null) {
die("$var needs to have a value");
}
}
?>
__autoload()
When an undefined class is initialized, the engine will automatically call the __autoload() interceptor function. The class name is passed to it as a unique parameter of the __autoload() interceptor function.
example:
<?php
function __autoload($className) {
include_once $className . ".php";
}
$object = new ClassName;
?>
Overloading of method and property calls
The general __call(), __get() and __set() methods can overload method and property calls.
Examples: __get() and __set()
<?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);
?>
Example: __call()
<?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);
?>