自 php 5.3.0 起,PHP 增加了一個叫做后期靜態綁定的功能,用于在繼承范圍內引用靜態調用的類。
使用 self:: 或者 __CLASS__ 對當前類的靜態引用,取決于定義當前方法所在的類:
<?phpclass 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();?> 解釋:定義當前test方法的類為A,所以self代表類A。輸出結果為:A
static::
<?phpclass A { public static function who() { echo __CLASS__; } public static function test() { static::who(); // 后期靜態綁定從這里開始 }}class B extends A { public static function who() { echo __CLASS__; }}B::test();?> 解釋:static::不再被解析為定義當前方法所在的類,而是在實際運行時計算的。輸出結果為:B
2.在非靜態環境下,所調用的類即為該對象實例所屬的類。由于 $this-> 會在同一作用范圍內嘗試調用私有方法,而static:: 則可能給出不同結果。另一個區別是static:: 只能用于靜態屬性。
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();解釋:類C中沒有test()方法,所以類C的實例調用父類A中的test方法,此時處于父類A的作用于域中,無法調用C::foo()這私有方法,所以在使用static::foo()時會報錯Fatal error: Call to private method C::foo() from context 'A' ,但$this會嘗試調用同一作用域中的私有方法,即無法調用當前對象c的方法,就調用它父類的。輸出結果為:
success! success! success!
( ! ) Fatal error: Call to private method C::foo() from context 'A' |
---|
3.后期靜態綁定的解析會一直到取得一個完全解析了的靜態調用為止。另一方面,如果靜態調用使用 parent:: 或者self:: 將轉發調用信息。
轉發和非轉發調用
<?phpclass 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();?> 解釋:所謂的"轉發調用"(forwarding call)指的是通過以下幾種方式進行的靜態調用:self::,parent::,static:: 以及forward_static_call()??捎胓et_called_class() 函數來得到被調用的方法所在的類名,static:: 則指出了其范圍。
A::foo() 靜態直接指名到姓的調用A內靜態函數,輸出A
parent::foo()是調用上一級的父類中的方法 ,此處為A,self::調用自身(類B)的foo()方法,類B中沒有foo()方法,則調用類A中的foo()方法。
A,B,C三個類里都有同一個名稱who()方法,根據覆蓋效應。系統會用優先級最高的,即C中的。輸出:C C
新聞熱點
疑難解答
圖片精選