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();
?>
公有和回护办法
在PHP 5(ZEND引擎2)中,还引入了公有和回护办法。
例:
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();
?>
之前代码中的用户自界说类或办法中虽不决义"public," "protected" 或 "private"等关头字,但无需编纂便可运转。
笼统类和办法
PHP 5还引入了笼统类和办法。笼统办法只声明办法界说, 不供实践运转。包括笼统办法的类需求声明为笼统类。
例:
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”关头字,但无需编纂便可运转。
接口
ZEND引擎2.0引入了接口。一个类可以运转恣意的接口列表。
Example
例:
interface Throwable {
public function getMessage();
}
class Exception implements Throwable {
public function getMessage() {
// ...
}
?>
之前代码中的用户自界说类或办法中虽不决义"interface”关头字,但无需编纂便可运转。
类类型界说
在保存类无需界说类型的同时,PHP 5引入了类类型界说来声明但愿把哪一个类经由过程参数传递给一个办法。
Example
例:
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);
?>
这些类类型界说在不象一些需求类型预界说的言语在编译中停止反省,而是在运转时停止。这意味着:
function foo(ClassName $object) {
// ...
}
?>
等价于:
function foo($object) {
if (!($object instanceof ClassName)) {
die("Argument 1 must be an instance of ClassName");
}
}
?>
本语法只用于对象或类,不合用于内建类型。
final
PHP 5引入了“final”关头字界说在子类中不克不及被掩盖的成员或办法。
例:
class Foo {
final function bar() {
// ...
}
}
?>
之前代码中的用户自界说类或办法中虽不决义"final"关头字,但无需编纂便可运转。
对象克隆
PHP 4在对象被复制时,用户不克不及决意拷贝的机制。在复制时,PHP 4只一名一名地复制一个和本来对象如出一辙的复成品。
咱们并非每次都要创立一个完整一样的复成品。一个很好的需求一种复制机制的例子是,当有一个代表一个GTK窗口的对象,它具有该窗口的一切资本,当你创立一个拷贝时,你能够需求一个新的窗口,它具有原窗口的一切属性,但需求具有新窗口的资本。别的一个例子是你有一个对象援用了别的一个对象,当你复制父对象时,你但愿创立谁人援用对象的新实例,以使复成品援用它。
对一个对象的拷贝经由过程挪用对象的__clone()办法完成:
$copy_of_object = $object->__clone();
?>
当开辟者恳求创立一个对象的新的拷贝时,ZEND引擎会反省是不是界说了__clone()办法。假如不决义的话,它会挪用一个默许的__clone()办法来复制该对象的一切属性。假如界说了该办法,该办法会担任在拷贝中设置需要的属性。为便利起见,引擎会供应一个函数从源对象中导入一切的属性,如许它就能够先失掉一个具有值的源对象拷贝,只需求对需求改动的属性停止掩盖便可。
例:
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";
?>
一致的机关办法名
ZEND引擎答应开辟者界说类的机关办法。具有机关办法的类在新建时会起首挪用机关办法,机关办法合用于在正式利用该类行进行的初始化。
在PHP4中,机关办法的称号与类名不异。因为在派生类中挪用父类的作法对照广泛,因而招致在PHP4中当类在一个大型的类承继中停止挪动时,处置体例有点愚笨。当一个派生类被挪动到一个分歧的父类中时,父类的机关办法名必定是分歧的,如许的话派生类中的有关挪用父类机关办法的语句需求改写。
PHP 5 introduces a standard way of declaring constructor methods by calling them by the name __construct().
PHP5引入了办法名__construct()来界说机关办法。
Example
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();
?>
为向下兼容,PHP5当在类不克不及找到__construct()办法时,会经由过程老的办法也就是类名来查找机关办法。这意味着独一能够发生兼容性成绩的是在之前的代码中已利用了一个名为__construct()的办法名。
析构办法
界说析构办法是非常有效的。析构办法可以纪录调试信息,封闭数据库毗连,还有做其它的收尾任务。PHP4中并没有此机制,虽然PHP已撑持注册在恳求停止时需求运转的函数。
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引入了与其它面向对象言语如Java言语类似的析构办法:当最初一个该对象的援用被排除时,体系将会在该对象从内存中释放前挪用名为__destruct()的析构办法。
例:
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
PHP5答应常量中有表达式,但在编译经常量中的表达式将被盘算.,因而常量不克不及在运转中改动它的值。
class Bar {
const a = 1<<0;
const b = 1<<1;
const c = a | b;
}
?>
之前代码中的用户自界说类或办法中虽不决义"const”关头字,但无需编纂便可运转。
破例
PHP 4 had no exception handling. PHP 5 introduces a exception model similar to that of other programming languages.
PHP4中无破例处置,PHP5援用了与其它言语类似的破例处置模子。
例:
class MyExceptionFoo extends Exception {
function __construct($exception) {
parent::__construct($exception);
}
}
try {
throw new MyExceptionFoo("Hello");
} catch (MyException $exception) {
print $exception->getMessage();
}
?>
之前代码中的用户自界说类或办法中虽不决义'catch', 'throw' 和 'try'关头字,但无需编纂便可运转。
函数前往对象值
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:
在PHP4中,函数不成能前往对象的值并对前往的对象停止办法挪用,经由过程ZEND引擎2中,这一切变得能够:
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();
?>
静态类中的静态成员变量如今可初始化
Example
class foo {
static $my_static = 5;
}
print foo::$my_static;
?>
静态办法
PHP5引入了关头字'static'来界说一个静态办法,如许可以从对象外停止挪用。
例:
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
?>
虚拟变量$this在静态办法中有效。
instanceof
PHP5引入了关头字instanceof来肯定一个对象是不是是某一个对象的实例,或某一个对象的派生,或利用了某一个接口。
例:
class baseClass { }
$a = new baseClass;
if ($a instanceof basicClass) {
echo "Hello World";
}
?>
静态函数变量
一切的静态变量如今在编译时停止处置,这答应开辟者经由过程援用来指定静态变量。这个变更进步了效力但意味着不成能对静态变量停止直接援用。
函数中经由过程按地址传送体例的参数答应界说默许值
例:
function my_function(&$var = null) {
if ($var === null) {
die("$var needs to have a value");
}
}
?>
__autoload()
在初始化一个不决义的类时,引擎将主动挪用__autoload()拦阻器函数。该类名将作为__autoload()拦阻器函数独一参数传递给它。
例:
function __autoload($className) {
include_once $className . ".php";
}