New Object Model
The object handling part in PHP has been completely rewritten with better performance and more features. In previous versions of PHP, objects were treated as primitive simple types
(such as integer and string). The disadvantage of this approach is that when variables are assigned or passed as parameters, a copy of the object is obtained. In the new version,
objects are referenced through handles, not through the object's value (the handle is imagined as the identifier of the object).
Many PHP programmers may not be aware of the "copying quirks" of the old object model, so most previous PHP programs will run without any changes
or with only minimal changes.
Private and protected members
PHP 5 introduces private and protected member variables, which can define visual class properties.
Example
Protected member variables can be accessed in subclasses of this class, while private member variables can only be accessed in the class to which they belong.
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; /* No content is output, the following is similar*/
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 protected methods
In PHP 5 (ZEND Engine 2), private methods and protected methods were also introduced.
Example:
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 the user-defined classes or methods in the previous code did not define keywords such as "public," "protected" or "private", But it works without modification.
Abstract classes and methods
PHP 5 also introduces abstract classes and methods. Abstract methods only declare the "symbol" of the method without providing its implementation. A class containing abstract methods needs to be declared "abstract".
For example:
phpabstract 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 is not defined in the user-defined classes or methods in the old code, it can run without modification.
Interfaces
ZEND Engine 2.0 introduces interfaces. A class can implement any list of interfaces.
For example:
User in old code Although the "interface" keyword is not defined in the defined class or method, it can run normally without modification.
Class Type Hints (Class Type Hints)
While retaining the need for classes to define types, PHP 5 introduces class type hints to declare in order to pass the class of an object to a method through parameters.
For example:
a($b);$a->b ($b);?>
These class type hints are not checked at compile time like some languages that require type definitions, but at runtime. This means:
is equivalent to:
This syntax is only used for objects or classes, not for built-in )type.
Final keyword (final)
PHP 5 introduced the "final" keyword to define members or methods that cannot be overridden in subclasses.
Example:
class Foo { final function bar() { // ... }}?>
In user-defined classes or methods in previously written code Although the "final" keyword is not defined, it can be run without modification.
Object Cloning
In PHP 4, when an object is copied, the user cannot determine which copy constructor to run. When copying, PHP 4 makes an identical copy bit by bit based on the object's properties
.
Building an exact replica every time is not always what we want. A good example of a copy constructor is when you have an object representing a GTK window, which owns all the resources for that window. When you create a copy, you may need a new window, which Has all the properties of the original window, but needs the resources of the new window. Another example is if you have a
object that references another object, and when you copy the parent object, you want to create a new instance of that referenced object so that the duplicate has a separate copy.
Copying an object is completed by calling the __clone() method of the object:
$copy_of_object = $object->__clone();
?>
When a developer requests to create a new copy of an object, the ZEND engine will check whether the __clone() method has been defined. If
is not defined, it will call a default __clone() method to copy all properties of the object. If this method is defined, it is responsible for
setting the necessary properties in the copy. For ease of use, the engine will provide a function to import all attributes from the source object, so that it can first get a copy of the source object with a value, and then only need to overwrite the attributes that need to be changed.
Example:
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";
?>
Uniform construction method
The ZEND engine allows developers to define the construction method of a class. When a class with a constructor method is created, the constructor method will be called first. The constructor
method is suitable for initialization before the class is officially used.
In PHP4, the name of the constructor is the same as the class name. Due to the common practice of calling parent classes in derived classes, the way in
PHP4 is a bit awkward when classes are moved within a large class inheritance. When a derived class is moved to a parent class with a different
, the constructor name of the parent class must be different. In this case, the statements about calling the parent class constructor in the derived class need to be rewritten.
PHP5 introduces a standard way of defining constructors by calling their __construct().
Example:
class BaseClass {
function __construct() {
print "In BaseClass constructorn";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructorn";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
For backward compatibility, when the PHP5 class cannot find the __construct() method, the old method will be used That is, the class name
is used to find the constructor. This means that the only possible compatibility issue is if a method name called __construct() has been used in previous code.
Destruction method
It is very useful to define the destruction method. The destructor method can record debugging information, close the database connection, and do other cleanup work. There is no such mechanism in PHP 4, although PHP already supports registering functions that need to be run at the end of the request.
PHP5 introduces a destructor method similar to other object-oriented languages such as Java: when the last reference to the object is cleared,
The system will call a method called __destruct before the object is released from memory. () destructor method.
Example:
class MyDestructableClass {
function __construct() {
print "In constructorn";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "n";
}
}
$obj = new MyDestructableClass();
?>
Similar to the constructor method, the engine will not call the destructor method of the parent class. To call this method, you need to call the destructor method of the child
class Called through the parent::__destruct() statement.
Constant
PHP 5 introduces the definition of per-class constants:
class Foo {
const constant = "constant";
}
echo "Foo::constant = " . Foo::constant . "n";
?>
PHP5 allows expressions in constants, but expressions in constants at compile time The formula will be evaluated,
so the constant cannot change its value on the fly.
class Bar {
const a = 1<<0;
const b = 1<<1;
const c = a | b;
}
?>
Although the "const" keyword is not defined in the user-defined classes or methods in the previous code,
it can run without modification.
Exceptions
There is no exception handling in PHP4. PHP5 introduces an exception handling model similar to other languages.
class MyExceptionFoo extends Exception {
function __construct($exception) {
parent::__construct($exception);
}
}
try {
throw new MyExceptionFoo("Hello");
} catch (MyExceptionFoo $exception) {
print $exception->getMessage();
}
?>
Although the 'catch', 'throw' and 'try' keywords are not defined in the user-defined classes or methods in the previous code, they can run without modification
.
Function returns object value
In PHP4, it is impossible for a function to return the value of an object and make method calls on the returned object. With the emergence of Zend Engine 2
(ZEND Engine 2), the following Calling is possible:
class Circle {
function draw() {
print "Circlen";
}
}
class Square {
function draw() {
print "Squaren";
}
}
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 can be initialized
For example:
class foo {
static $my_static = 5;
}
print foo::$my_static;
?>
Static Methods
PHP5 introduced the keyword 'static' to define a static method, which can be called from outside the object.
For example:
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
?>
The virtual variable $this is not valid in a method defined as static.
Instanceof
PHP5 introduced the "instanceof" keyword to determine whether an object is an instance of an object, a derivative of an object, or uses an interface.
Example:
class baseClass { }
$a = new baseClass;
if ($a instanceof basicClass) {
echo "Hello World";
}
?>
Static function variables (Static function variables)
All static variables are now being compiled This allows developers to specify static variables by reference. This change improves efficiency but means that indirect references to static variables are not possible.
Parameters passed by reference in functions are allowed to have default values
For example:
function my_function(&$var = null) {
if ($var === null) {
die("$var needs to have a value");
}
}
?>
__autoload()
When initializing an undefined class, the __autoload() interceptor function will be automatically called
. The class name will be passed to the __autoload() interception function as the only parameter.
For example:
function __autoload($className) {
include_once $className . ".php";
}
$object = new ClassName;
?>
Overloading of method and attribute calls
All method calls and attribute accesses can be overloaded using the __call(), __get() and __set() methods load.
Example: __get() and __set()
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: $rn";
return $r;
} else {
print "Nothing!n";
}
}
function __set($nm, $val) {
print "Setting [$nm] to $valn";
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()
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);
?>