PHP處理物件部分的核心完全重新開發過,提供更多功能的同時也提高了效能。在先前版本的php中,處理物件和處理基本類型(數字,字串)的方式是一樣的。這種方式的缺陷是:當物件賦值給一個變數時,或透過參數傳遞物件時,物件將被完全拷貝一份。在新的版本裡,上述操作將傳遞引用(可以把引用理解成物件的識別碼),而非值。
許多PHP程式設計師可能甚至沒有察覺到老的物件處理方式。事實上,大多數的php應用都可以很好地運行。或僅僅需要很少的改動。
私有和受保護成員
PHP5引入了私有和受保護成員變數的概念。我們可以用它來定義類別成員的可見性。
範例
受保護成員可以被子類別訪問, 而私有成員只能被類別本身存取。
class MyClass {
private $Hello = "Hello, World!n";
protec Hello, Bar!n";
function printHello() {
print "MyClass::printHello() " this- >Bar;
print "MyClass::printHello() " . $this->Foo;
}
} MyClass::printHello(); MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
print "MyClass2::printHello() " . $this->Bar; /* Shouldn't print (not declared)*/ /* Should print */
}
}
$obj = new MyClass();
print $obj->Hello; / Shouldn't print $obj->Hello; / Shouldn't print >Bar; /* Shouldn't print out anything */
print $obj->Foo; /* Shouldn't print out anything
$obj = new MyClass2();
print $obj->Hello; /* Shouldn't print out anything */
/
print $obj->Foo; /* Shouldn't print out anything */
$obj->printHello();
?>
$obj->printHello();
?>
私有方法與受保護方法和受保護方法🎜>也引入了私有方法和受保護方法的概念。
範例:
class Foo {
private function aPrivateMethod() {
🎜> protected function aProtectedMethod() {
echo "Foo::aProtectedMethod() called.n";
extends Foo {
public function aPublicMethod() {
echo "Bar::aPublicMethod() called.n";
o = new Bar ;
$o->aPublicMethod();
?>
以前的不使用類別的舊程式碼,沒有存取修飾符(public, protected, private)的程式碼可以不經改動運作。
抽象類別和抽象方法
Php5也引入了抽象類別和抽象方法的概念。抽象方法只是聲明了方法的簽章並不提供它的實作。包含抽象方法的類別必須被宣告成抽象類別。
範例:
abstract class AbstractClass {
abstract public function test();
.publictest function test();
. () {
echo "ImplementedClass::test() called.n";
}
}
$o = at> >抽象類別不能被實例化。以前的不使用抽象類別的老程式碼可以不經改動運行。
介面
Php5引入了介面。一個類別可以實作多個介面。
範例:
interface Throwable {
public function getMessage();
} // ...
}
}
?>
以前的不使用介面的舊程式碼可以不經改動運作
類型的類型提示
PHP55🎜>
類型的類型提示
PHP5依然是弱型的,不過在定義函數參數時,可以使用類別的類型提示來宣告期望傳入的物件類型
Example
interface Foo {
function a(Foo $foo);
}
interface Bar {
function b(Bar $bar);
}
class FooBar 選項
// ...
}
function b(Bar $bar) {
new FooBar;
$b = new FooBar;
$a->a($b);
$a->b($b);
?>
和其他強型別語言一樣,php5類的類型提示在執行期間檢查而非編譯期間檢查。即:
function foo(ClassName $object) {
// ...
}
?>
和下面的程式碼是一樣的:下面的程式碼是一樣的: function foo($object) {
if (!($object instanceof ClassName)) {
}
}
?>
這個語法只適用於類,不適用於內建類型。
Final
PHP 5 引入了final關鍵字來宣告final成員和final方法。 final成員和final方法不能被子類別覆蓋。
Example
class Foo {
final function bar() {
進一步,可以把類別聲明成final。將類別宣告成final可以阻止這個類別被繼承。 final類別裡面的方法缺省地都是final的,無需再聲明一次。
Example
final class Foo {
// class definition
}
// thenext definition
}
// thenext definition
}
// thenext line款🎜>?>
屬性不能定義成為final.
以前的不使用final的老代碼可以不經改動運行.
對象克隆
Php4沒有提供一種機制來讓用戶自己定義複製構造子(copy constructor)控制物件的複製過程。 Php4做二進位的拷貝,因而很精確地複製了物件的所有屬性。
精確地複製物件的所有屬性可能並不是我們一直想要的。有個例子可以很好地說明我們確實需要複製構造子:例如一個GTK Window的物件 a。 a持有它所需的全部資源。當複製的這個GTK Window到物件b時候,我們更希望b持有新的資源物件。再舉個例子:對象a包含了一個對象c, 當你把對象a 複製到對象c的時候。我們可能更希望物件b包含一個新的物件c的copy, 而不是一個物件c的引用。 (譯者註:這裡所說的就是淺克隆和深克隆。)
物件的複製是透過clone這個關鍵字達到的(Clone調用被克隆物件的__clone()方法)。物件的__clone方法不能夠直接被呼叫。
$copy_of_object = clone $object;
?>
當developer創建物件的一份拷貝的時候,php5將會檢查 __clone()方法是否存在。如果不存在,那麼它就會呼叫缺省的__clone()方法,複製物件的所有屬性。如果__clone()方法已經定義過,那麼_clone()方法就會負責設定新物件的屬性。為了方便起見,Engine會缺省地複製所有的屬性。所以在__clone()方法中,只需要覆寫那些需要改變的屬性就可以了。如下:
Example
class MyCloneable {
static $id = 0;
++;
}
function __clone() {
$this->address = "New }
}
$obj = new MyCloneable();
$obj->name = "Hello";
$obj->address = "Tel-Aviv";
print $obj-> ";
$obj_cloned = clone $obj;
print $obj_cloned->id . "n";
print $obj_cloned-> . "n";
?>
統一建構子
Php5允許開發者宣告一個類別的建構方法。擁有構造方法的類別在每次創建新的物件的時候都會呼叫這個方法,因此構造方法適合物件在被使用之前的初始化工作
Php4中,構造方法的名稱和類別的名稱一樣。考慮到從子類別構造方法呼叫父類別構造方法的情況是非常普遍的,而將類別從一個繼承體系中搬遷引起的父類別變更就常常導致需要更改類別的建構方法,php4的做法顯然是不太合理的。
Php5引入了一個聲明建構函數的標準方法: __construct().如下:
Example
class BaseClass {
BaseClass constructorn";
}
}
class SubClass extends BaseClass {
function __structstruct()::
function __” print "In SubClass constructorn";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
為保持向後的,如果php5兼容性(),它會尋找老式的建構方法,也就是與類別同名的方法。簡單的說,只有當舊程式碼裡包含了一個__construct()方法的時候,才存在一個相容性的問題。
析構方法
對於物件導向的程式設計來說,可以定義析構方法是非常有用的一個功能。析構方法可以用來記錄偵錯訊息,關閉資料庫連線等等一些清除收尾的工作。 Php4中沒有析構方法,儘管php4已經支援可以註冊一個函數以便請求結束的時候被呼叫。
Php5引進的析構方法的概念和其他物件導向的語言(如java)是一致的。當指向這個物件的最後一個引用被銷毀的時候,析構方法被調用,調用完成後釋放記憶體。注意:析構方法不接受任何參數。
Example
class MyDestructableClass {
function __construct() {
MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . 🎜>?>
和建構方法一樣,父類別的析構方法也不會被隱含呼叫。子類別可以在自己的析構方法透過呼叫parent::__destruct()來明確地呼叫它。
Constants
Php5引入了class等級的常數。
class Foo {
const constant = "constant";
}
echo "Foo::constant";
}
echo "Foo::constant ?>
老的沒有使用const的程式碼還是正常運作。
Exceptions
Php4沒有異常控制。 Php5引入了與其它語言(java)相似的異常控制模式。應該注意的是php5裡面支援捕捉全部異常,但不支援finally子句。
在catch語句區塊裡面,可以重新拋出異常。也可以有多個catch語句,在這種情況下,被捕捉到的異常從上往下依序比較和catch語句比較異常,第一個類型匹配的catch語句將會被執行。如果一直搜尋到底還沒發現符合的catch子句,則尋找下一個try/catch語句。最後不能捕捉的異常將會被顯示出來。如果異常被捕捉,那麼程式就會接著catch語句塊的下面開始執行。
Example
class MyException {
function __construct($exception) {
function Display() {
print "MyException: $this->exceptionn";
}
}
class MyEx 🎜> $this->exception = $ exception;
}
function Display() {
print "MyException: 5$>exceptionn"; throw new MyExceptionFoo('Hello ');
}
catch (MyException $exception) {
$exception->Display();
}
(Exception> 🎜>}
?>
上面的例子表明可以定義一個並不繼承自 Exception的異常類,但是,最好還是從Exception繼承並定義自己的異常。這是因為系統內建的Exception類別能夠收集到很多有用的信息, 而不繼承它的異常類別是得不到這些資訊的。下面的php程式碼模仿了系統內建Exception類別。每個屬性後面都加了註解。每個屬性都有一個getter,由於這些getter方法經常被系統內部處理調用,所以這些方法被標明了final。
範例
class Exception {
function __construct(string $message=NULL, int code=0) {
}
$this->code = $code;
>line = __LINE__; // 拋出子句
$this->trace = debug_backtrace();
$this->string = StringFormat($this); 異常'; // 異常訊息
受保護的$code = 0; // 使用者定義的例外代碼
protected $file; //原始碼行
private $trace; // 異常
的回溯private $string; // 僅限內部!
最終函數 getMessage() {
return $this->message;
} }
最終函數getFile() {
return $this->file;
}
最終函數getTrace() {
最終函數getTraceAsString() {
return self::TraceFormat($this);
}
函數 _toString() 靜態私人函數 StringFormat(Exception $ exception) {
//... PHP 腳本中不可用的函數
// 以字符串形式返回所有相關信息
}
靜態私有函數 TraceFormat(Exception $exception) {
// ... PHP 腳本中不可用的函數
//以字串形式回溯
}
}
? >
如果我們定義的異常類別都是繼承自Exception基底類別
無相容性問題。舊的程式碼不會受到這個特性的影響。
取消引用從函數傳回的物件
Php4中不能再次引用函數傳回的物件以進一步呼叫傳回物件的方法,而php5是可以的。
class Circle {
function draw() {
print "Cirareclen} print "Squaren";
}
}
函數ShapeFactoryMethod($shape) { return new Circle( );
case "Square":
return new Square()
return new Square();
return new Square();
re找到ShapeFactoryMethod("Square ")->draw();
? >
靜態成員變數能夠被初始化。
Example
class foo {
static $my_static = 5;
public $my_prop = 5;
public $my_prop = 5;
public $my_prop =
$obj = new foo;
print $obj->my_prop;
?>
靜態方法
PHP 5 引入了靜態方法,可以在不調用實例化類別的情況下呼叫靜態方法。
Example
class Foo {
public static function aStaticMethod() {
( );
?>
偽變數$this不能夠在靜態方法方法中使用。
instanceof
Php5引入了instanceof關鍵字,允許用它來測試一個物件是一個類別的實例,或者是一個派生類別的實例,或者實現了某個介面
Example
php
class baseClass { }
$a = new baseClass;
if ($a instanceof baseClass) {
echoo>DH baseClass) {
echoo>DH baseClass) > function variables
現在,靜態變數在編譯階段處理。因此程式設計師可以透過引用為靜態變數賦值。這可以改善效能,不過,不能夠使用對靜態變數的間接引用了。
按引用傳遞的函數參數現在也可以設定缺省值了。
Example
function my_function(&$var = null) {
if ($var === null) {
die("$var needs to have a value" );
}
}
?>
__autoload()
__autoload() 攔截函數在一個未宣告的類別被初始化的時候自動呼叫。這個類別的名字會自動傳遞給__autoload()函數。而__autoload()也只有這麼唯一的一個參數。
Example
function __autoload($className) {
include_once $className . ".php";
}
}
可重載的方法呼叫和屬性存取
方法呼叫和屬性存取都能夠透過__call, __get() and __set()方法重載。
範例:__get() 且__set()
class Setter {
public $n;
public $x = array("a" => 1, "b " => 2, "c" => 3);
函數 __get($nm) {
列印「取得[$nm]n」; $r = $this->x[$nm];
🎜> } else {
以印刷上「沒什麼! if (isset($ this->x[$nm])) {
$this->x[$nm] = $val;
🎜> 則以「不行! 🎜>$foo->a++;
$foo->z++;
var_dump($foo);
? >
範例:__call()
class Caller {
private $x =array(1, 2, 3);
print 「方法$m 呼叫:n」;
var_dump($a);
Caller() ;
$a = $foo->test(1,"2", 3.4, true);
var_dump($a);
? >
迭代
當和 foreach 一起使用物件的時候,迭代的方式被重載了。重點的行為是迭代類別的所有屬性。
範例
類別 Foo {
public $x = 1;
公公$ foreach ($obj as $prp_name => $prop_value) {
// 使用屬性
}
?>;
一個類別的所有物件都能夠被迭代瀏覽到,如果這個類別實作了一個空的介面:Traversable。 因此,實作了Traversable介面的類別可以和foreach一起使用。
介面 IteratorAggregate 和Iterator指定類別的物件如何在程式碼中迭代。IteratorAggregate介面有一個方法:getIterator()必須回傳一個陣列
範例
class ObjectIterator implements Iterator {
($obj) {
$this->obj = $obj;
}
🎜> 函數valid( ) {
return $this->num obj->max;
}
}
function current() {
switch($this->num) {
情況1:返回「2nd」;
狀況2:回「3rd」 ;
預設:回傳$this->num."th";
}
num++;
}
}
類別物件實作IteratorAggregate {
public $max = 3;
函數getIterator() {
j =新物件;
// 這個foreach ...
foreach($obj as $key => $val) {
echo "$key = $valn";
}
/$//$將以下7 行與for 指令相符。
$it = $obj->getIterator();
for($it->rewind(); $it->hasMore(); $it->next) {
$key = $itit ->current();
$val = $it->key();
echo "$key = $valn";
}
未設定($it)
; >
新的__toString方法
可以透過覆寫__toString方法來控制物件到字串的轉換。
範例
class Foo {
function __toString() {
🎜>回顯$obj; // 呼叫__toString()
?>;
Reflection API
Php5 引入了的引用API,以支援對類別、介面、函數、方法的反向工程。
它還提供了 API 以從程式中取得註釋文件。引用API 的詳細資料請參考此處:http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html
Example
class Foo {
$prop ;
函數Func($name) {
echo 「Hello $name」;
}
}
reflection_method::export('Foo', 'func');
reflection_property::export('Foo', 'prop');
reflection_extension::export('標準標準');
? >
新的記憶體管理機制
Php5 有一個全新的記憶體管理機制,使得它在多執行緒的環境下可以更有效地運作。在分配和釋放記憶體時,不再使用互斥鎖/解除鎖定
以上就介紹了h5 PHP5新功能:更針對物件化的PHP,包括了h5方面的內容,希望對PHP教學有興趣的朋友有幫助。