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