《PHP實(shí)例:php5.3后靜態(tài)綁定用法詳解》要點(diǎn):
本文介紹了PHP實(shí)例:php5.3后靜態(tài)綁定用法詳解,希望對您有用。如果有疑問,可以聯(lián)系我們。
本文實(shí)例講述了php5.3后靜態(tài)綁定用法.分享給大家供大家參考,具體如下:PHP學(xué)習(xí)
手冊原文:PHP學(xué)習(xí)
自 PHP 5.3.0 起,PHP 增加了一個(gè)叫做后期靜態(tài)綁定的功能,用于在繼承范圍內(nèi)引用靜態(tài)調(diào)用的類.PHP學(xué)習(xí)
準(zhǔn)確說,后期靜態(tài)綁定工作原理是存儲(chǔ)了在上一個(gè)"非轉(zhuǎn)發(fā)調(diào)用"(non-forwarding call)的類名.當(dāng)進(jìn)行靜態(tài)方法調(diào)用時(shí),該類名即為明確指定的那個(gè)(通常在 :: 運(yùn)算符左側(cè)部分);當(dāng)進(jìn)行非靜態(tài)方法調(diào)用時(shí),即為該對象所屬的類.所謂的"轉(zhuǎn)發(fā)調(diào)用"(forwarding call)指的是通過以下幾種方式進(jìn)行的靜態(tài)調(diào)用:self::,parent::,static:: 以及 forward_static_call().可用 get_called_class() 函數(shù)來得到被調(diào)用的方法所在的類名,static:: 則指出了其范圍.PHP學(xué)習(xí)
該功能從語言內(nèi)部角度考慮被命名為"后期靜態(tài)綁定"."后期綁定"的意思是說,static:: 不再被解析為定義當(dāng)前方法所在的類,而是在實(shí)際運(yùn)行時(shí)計(jì)算的.也可以稱之為"靜態(tài)綁定",因?yàn)樗梢杂糜?但不限于)靜態(tài)方法的調(diào)用.PHP學(xué)習(xí)
self:: 的限制PHP學(xué)習(xí)
使用 self:: 或者 __CLASS__ 對當(dāng)前類的靜態(tài)引用,取決于定義當(dāng)前方法所在的類:PHP學(xué)習(xí)
Example #1 self:: 用法PHP學(xué)習(xí)
<?php class A { public static function who() { echo __CLASS__; } public static function test() { self::who(); } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); ?>
以上例程會(huì)輸出:PHP學(xué)習(xí)
APHP學(xué)習(xí)
后期靜態(tài)綁定的用法 后期靜態(tài)綁定本想通過引入一個(gè)新的關(guān)鍵字表示運(yùn)行時(shí)最初調(diào)用的類來繞過限制.簡單地說,這個(gè)關(guān)鍵字能夠讓你在上述例子中調(diào)用 test() 時(shí)引用的類是 B 而不是 A.最終決定不引入新的關(guān)鍵字,而是使用已經(jīng)預(yù)留的 static 關(guān)鍵字.PHP學(xué)習(xí)
Example #2 static:: 簡單用法PHP學(xué)習(xí)
<?php class A { public static function who() { echo __CLASS__; } public static function test() { static::who(); // 后期靜態(tài)綁定從這里開始 } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); ?>
以上例程會(huì)輸出:PHP學(xué)習(xí)
BPHP學(xué)習(xí)
Note: 在非靜態(tài)環(huán)境下,所調(diào)用的類即為該對象實(shí)例所屬的類.由于 $this-> 會(huì)在同一作用范圍內(nèi)嘗試調(diào)用私有方法,而 static:: 則可能給出不同結(jié)果.另一個(gè)區(qū)別是 static:: 只能用于靜態(tài)屬性.PHP學(xué)習(xí)
Example #3 非靜態(tài)環(huán)境下使用 static::PHP學(xué)習(xí)
<?php class A { private function foo() { echo "success!\n"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /* foo() will be copied to B, hence its scope will still be A and * the call be successful */ } class C extends A { private function foo() { /* original method is replaced; the scope of the new one is C */ } } $b = new B(); $b->test(); $c = new C(); $c->test(); //fails ?>
以上例程會(huì)輸出:PHP學(xué)習(xí)
success!
success!
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9PHP學(xué)習(xí)
Note: 后期靜態(tài)綁定的解析會(huì)一直到取得一個(gè)完全解析了的靜態(tài)調(diào)用為止.另一方面,如果靜態(tài)調(diào)用使用 parent:: 或者 self:: 將轉(zhuǎn)發(fā)調(diào)用信息.PHP學(xué)習(xí)
Example #4 轉(zhuǎn)發(fā)和非轉(zhuǎn)發(fā)調(diào)用PHP學(xué)習(xí)
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { public static function who() { echo __CLASS__."\n"; } } C::test(); ?>
以上例程會(huì)輸出:PHP學(xué)習(xí)
A
C
CPHP學(xué)習(xí)
下面示例分析了基于PHP后期靜態(tài)綁定功能解決在繼承范圍內(nèi)引用靜態(tài)調(diào)用的類.PHP學(xué)習(xí)
先看如下代碼:PHP學(xué)習(xí)
class Person { public static function status() { self::getStatus(); } protected static function getStatus() { echo "Person is alive"; } } class Deceased extends Person { protected static function getStatus() { echo "Person is deceased"; } } Deceased::status(); //Person is alive
很明顯,結(jié)果不是我們預(yù)期的,這是因?yàn)閟elf::取決于定義時(shí)所在的類,而不是運(yùn)行中的類.為了解決這個(gè)問題,你可能會(huì)在繼承類中重寫status()方法,更好的解決方案是PHP 5.3后添加了后期靜態(tài)綁定的功能.PHP學(xué)習(xí)
代碼如下:PHP學(xué)習(xí)
class Person { public static function status() { static::getStatus(); } protected static function getStatus() { echo "Person is alive"; } } class Deceased extends Person { protected static function getStatus() { echo "Person is deceased"; } } Deceased::status(); //Person is deceased
可見,static::不在指向當(dāng)前所在的類,實(shí)際上,它是在運(yùn)行中計(jì)算的,強(qiáng)制獲取最終類的所有屬性.PHP學(xué)習(xí)
因此,建議,以后不要再使用self::,使用static::PHP學(xué)習(xí)
補(bǔ)充:PHP學(xué)習(xí)
網(wǎng)友帖1PHP學(xué)習(xí)
php的后期靜態(tài)綁定,怎么解釋?下面的這幅圖輸出是A,C,CPHP學(xué)習(xí)
PHP學(xué)習(xí)
由圖的繼承關(guān)系可知:C徹底包含了B和A.PHP學(xué)習(xí)
在看答案結(jié)果以前,他細(xì)觀察發(fā)現(xiàn),三個(gè)類里都有同一個(gè)名稱who()方法.
系統(tǒng)會(huì)用最后一個(gè)優(yōu)先級最高,進(jìn)一步的說,你幾乎沒法通過C去調(diào)用A、B內(nèi)的who(),只能重改方法,比如添加個(gè)getBWho(){echo B::who();}
然后通過C::getBWho();來調(diào)用B內(nèi)的who();PHP學(xué)習(xí)
下面來看運(yùn)行結(jié)果:PHP學(xué)習(xí)
test只在B中出現(xiàn),所以結(jié)果必然是test()中運(yùn)行的三個(gè)結(jié)果:PHP學(xué)習(xí)
第一個(gè):靜態(tài)直接指名到姓的調(diào)用A內(nèi)靜態(tài)函數(shù),這沒有懸念,必然是A
第二個(gè):parent::是調(diào)用上一級的父類,在此題中為A,A中又直接調(diào)用static:who();上面說過了,這個(gè)who()優(yōu)先級最高的在C里面,無論在你ABC中哪里調(diào)用,只要是static::who()必然是最后定義的那個(gè),覆蓋效應(yīng),如果想調(diào)用A里的必需指明A::who()或是通過去除static從作用域限制來實(shí)現(xiàn).所以這個(gè)who()就是C中定義的who
第三個(gè):self::who與第二個(gè)類似的問題,看樣該走B的,注意覆蓋效應(yīng),要想調(diào)用B內(nèi)的who必須得B::who(),因?yàn)楦呒壍腃已經(jīng)重寫了這個(gè)方法,如果C中沒有who,肯定就是B,依次類推.所以必然還是調(diào)用C中的who;PHP學(xué)習(xí)
所以答案為:ACCPHP學(xué)習(xí)
代碼如下:PHP學(xué)習(xí)
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { //public static function who() { // echo __CLASS__."\n"; //} } C::test(); ?>
輸出為:A B BPHP學(xué)習(xí)
網(wǎng)友帖2PHP學(xué)習(xí)
(還是針對上面圖中的代碼)PHP學(xué)習(xí)
手冊不是說得很清楚么PHP學(xué)習(xí)
”后期綁定“的意思是說,static::不再被解析為定義當(dāng)前方法所在的類,而是在實(shí)際運(yùn)行時(shí)計(jì)算的.也可以稱之為”靜態(tài)綁定“,因?yàn)樗梢杂糜?但不限于)靜態(tài)方法的調(diào)用.PHP學(xué)習(xí)
#1說的有個(gè)小問題PHP學(xué)習(xí)
【self::foo(); // 這個(gè)self實(shí)際上是C類.明白嗎? C::test() C繼承了B的test()方法】PHP學(xué)習(xí)
不準(zhǔn)確,self還是B類,但是本身沒有覆寫foo方法,所以就調(diào)用父類A的foo方法.PHP學(xué)習(xí)
如果self實(shí)際是C類,那你試下self::foo();改成self::who();,應(yīng)當(dāng)打印C,但是打印B,這也正是self和static的區(qū)別.PHP學(xué)習(xí)
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::who(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { public static function who() { echo __CLASS__."\n"; } } C::test(); ?>
輸出為:A C BPHP學(xué)習(xí)
網(wǎng)友帖3PHP學(xué)習(xí)
A::foo(); //A指代A類,訪問A類的foo方法和who方法 parent::foo();//調(diào)用B類的父類――A的foo方法,并告訴foo方法最原始的調(diào)用者是C self::foo(); //self指代定義該方法的類,即B,但是B沒有定義foo方法,它將原始的調(diào)用者C向上傳遞, // 訪問父類的foo方法,最后訪問c的who方法;
所以這就回答了樓上的疑問:若是把self::foo(); 改成self::who(),因?yàn)閟elf指代B,而B有who方法,所以結(jié)果是變成了BPHP學(xué)習(xí)
靜態(tài)調(diào)用使用 parent:: 或者 self:: 將轉(zhuǎn)發(fā)原始調(diào)用信息.PHP學(xué)習(xí)
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《PHP基本語法入門教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《PHP網(wǎng)絡(luò)編程技巧總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》PHP學(xué)習(xí)
希望本文所述對大家PHP程序設(shè)計(jì)有所幫助.PHP學(xué)習(xí)
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/2824.html