前言 今天突然想到PHP官方網站上一轉,一眼就看到PHP5推出的通告。雖然以前看到過PHP5的預告,但還是仔細看了PHP 5/Zend Engine 2.0新特性一文,一股JAVA氣息撲面而來... 特將該文試譯出來,首發於CSDN網站,以飨讀者。 PHP 5/Zend Engine 2.0新特性 徐喚春 譯 [email protected] http://www.php.net/zend-engine-2.php 全新的對象模型 PHP中的對象處理部分已完全重寫,具有更佳的性能和更多的功能。在PHP的以前版本中,對象與內建變量類型(如integer和string)的處理方法相同,其弊端是當變量被賦值為對象或對象作為參數傳遞時,得到的是對象復制品。而在新版本中,對象通過句柄進行引用,而不是通過它的值。(句柄可以認是為是對象的標識符) 很多PHP程序員可能未意識到以前的對象模型的“復制怪癖”,因此以前的PHP程序將不需要做任何更改,或只做很小的改動即可運行 私有和保護成員 PHP 5引入了私有和保護成員變量,它們可以定義類屬性在何時可以被訪問。 例 類的保護成員變量能在該類的擴展類中被訪問,而私有成員變量只能在本類中被訪問。 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; /* Shouldnt print out anything */ print "MyClass2::printHello() " . $this->Bar; /* Shouldnt print (not declared)*/ print "MyClass2::printHello() " . $this->Foo; /* Should print */ } } $obj = new MyClass(); print $obj->Hello; /* Shouldnt print out anything */ print $obj->Bar; /* Shouldnt print out anything */ print $obj->Foo; /* Shouldnt print out anything */ $obj->printHello(); /* Should print */ $obj = new MyClass2(); print $obj->Hello; /* Shouldnt print out anything */ print $obj->Bar; /* Shouldnt print out anything */ print $obj->Foo; /* Shouldnt print out anything */ $obj->printHello(); ?> 私有和保護方法 在PHP 5(ZEND引擎2)中,還引入了私有和保護方法。 例: aPrivateMethod(); } } class Bar extends Foo { public function aPublicMethod() { echo "Bar::aPublicMethod() called. "; $this->aProtectedMethod(); } } $o = new Bar; $o->aPublicMethod(); ?> 以前代碼中的用戶自定義類或方法中雖未定義"public," "protected" 或 "private"等關鍵字,但無需編輯即可運行。 抽象類和方法 PHP 5還引入了抽象類和方法。抽象方法只聲明方法定義, 不供實際運行。包含抽象方法的類需要聲明為抽象類。 例: test(); ?> 抽象類不能實例化。以前代碼中的用戶自定義類或方法中雖未定義"abstract”關鍵字,但無需編輯即可運行。 接口 ZEND引擎2.0引入了接口。一個類可以運行任意的接口列表。 Example 例: 以前代碼中的用戶自定義類或方法中雖未定義"interface”關鍵字,但無需編輯即可運行。 類類型定義 在保留類無需定義類型的同時,PHP 5引入了類類型定義來聲明希望把哪個類通過參數傳遞給一個方法。 Example 例: a($b); $a->b($b); ?> 這些類類型定義在不象一些需要類型預定義的語言在編譯中進行檢查,而是在運行時進行。這意味著: 等價於: 本語法只用於對象或類,不適用於內建類型。 final PHP 5引入了“final”關鍵字定義在子類中不能被覆蓋的成員或方法。 例: 以前代碼中的用戶自定義類或方法中雖未定義"final"關鍵字,但無需編輯即可運行。 對象克隆 PHP 4在對象被復制時,用戶不能決定拷貝的機制。在復制時,PHP 4只一位一位地復制一個和原來對象一模一樣的復制品。 我們並不是每次都要建立一個完全一樣的復制品。一個很好的需要一種復制機制的例子是,當有一個代表一個GTK窗口的對象,它擁有該窗口的所有資源,當你建立一個拷貝時,你可能需要一個新的窗口,它擁有原窗口的所有屬性,但需要擁有新窗口的資源。另外一個例子是你有一個對象引用了另外一個對象,當你復制父對象時,你希望建立那個引用對象的新實例,以使復制品引用它。 對一個對象的拷貝通過調用對象的__clone()方法完成: __clone(); ?> 當開發者請求建立一個對象的新的拷貝時,ZEND引擎會檢查是否定義了__clone()方法。如果未定義的話,它會調用一個默認的__clone()方法來復制該對象的所有屬性。如果定義了該方法,該方法會負責在拷貝中設置必要的屬性。為方便起見,引擎會提供一個函數從源對象中導入所有的屬性,這樣它就可以先得到一個具有值的源對象拷貝,只需要對需要改變的屬性進行覆蓋即可。 例: 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 . " "; $obj = $obj->__clone(); print $obj->id . " "; print $obj->name . " "; print $obj->address . " "; ?> 統一的構造方法名 ZEND引擎允許開發者定義類的構造方法。具有構造方法的類在新建時會首先調用構造方法,構造方法適用於在正式使用該類前進行的初始化。 在PHP4中,構造方法的名稱與類名相同。由於在派生類中調用父類的作法比較普遍,因此導致在PHP4中當類在一個大型的類繼承中進行移動時,處理方式有點笨拙。當一個派生類被移動到一個不同的父類中時,父類的構造方法名必然是不同的,這樣的話派生類中的有關調用父類構造方法的語句需要改寫。 PHP 5 introduces a standard way of declaring constructor methods by calling them by the name __construct(). PHP5引入了方法名__construct()來定義構造方法。 Example 為向下兼容,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 objects destructor, which is a class method name %__destruct()% that recieves no parameters, is called before the object is freed from memory. PHP5引入了與其它面向對象語言如Java語言相似的析構方法:當最後一個該對象的引用被清除時,系統將會在該對象從內存中釋放前調用名為__destruct()的析構方法。 例: name = "MyDestructableClass"; } function __destruct() { print "Destroying " . $this->name . " "; } } $obj = new MyDestructableClass(); ?> 和構造方法相似,引擎將不調用父類的析構方法,為調用該方法,你需要在子類的析構方法中通過parent::__destruct()語句進行調用。 常量 PHP 5 引入了類常量定義: PHP5允許常量中有表達式,但在編譯時常量中的表達式將被計算.,因此常量不能在運行中改變它的值。