PHP基礎之類和對象20——后期靜態綁定
自 PHP 5.3.0 起,PHP 增加了一個叫做后期靜態綁定的功能,用于在繼承范圍內引用靜態調用的類。
準確說,后期靜態綁定工作原理是存儲了在上一個“非轉發調用”(non-forwarding call)的類名。當進行靜態方法調用時,該類名即為明確指定的那個(通常在?::?運算符左側部分);當進行非靜態方法調用時,即為該對象所屬的類。所謂的“轉發調用”(forwarding call)指的是通過以下幾種方式進行的靜態調用:self::,parent::,static::?以及forward_static_call()。可用?get_called_class()?函數來得到被調用的方法所在的類名,static::?則指出了其范圍。
該功能從語言內部角度考慮被命名為“后期靜態綁定”。“后期綁定”的意思是說,static::?不再被解析為定義當前方法所在的類,而是在實際運行時計算的。也可以稱之為“靜態綁定”,因為它可以用于(但不限于)靜態方法的調用。
self::?的限制使用?self::?或者?__CLASS__?對當前類的靜態引用,取決于定義當前方法所在的類:
Example #1?self::?用法
<?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();?>
以上例程會輸出:
A后期靜態綁定的用法
后期靜態綁定本想通過引入一個新的關鍵字表示運行時最初調用的類來繞過限制。簡單地說,這個關鍵字能夠讓你在上述例子中調用?test()?時引用的類是?B?而不是?A。最終決定不引入新的關鍵字,而是使用已經預留的?static?關鍵字。
Example #2?static::?簡單用法
<?php class 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();?>
以上例程會輸出:
B
注意:
在非靜態環境下,所調用的類即為該對象實例所屬的類。由于?$this->?會在同一作用范圍內嘗試調用私有方法,而?static::?則可能給出不同結果。另一個區別是?static::只能用于靜態屬性。
Example #3 非靜態環境下使用?static::
<?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?>
以上例程會輸出:
success!success!success!Fatal error: Call to private method C::foo() from context ’A’ in /tmp/test.php on line 9
Note:
后期靜態綁定的解析會一直到取得一個完全解析了的靜態調用為止。另一方面,如果靜態調用使用?parent::?或者?self::?將轉發調用信息。
Example #4 轉發和非轉發調用
<?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();?>
以上例程會輸出:
ACC
相關文章:
1. 解決python腳本中error: unrecognized arguments: True錯誤2. Python使用jupyter notebook查看ipynb文件過程解析3. php的curl攜帶header請求頭信息實現http訪問的方法4. php網絡安全中命令執行漏洞的產生及本質探究5. IntelliJ IDEA創建普通的Java 項目及創建 Java 文件并運行的教程6. ajax請求添加自定義header參數代碼7. python利用os模塊編寫文件復制功能——copy()函數用法8. 無線標記語言(WML)基礎之WMLScript 基礎第1/2頁9. php測試程序運行速度和頁面執行速度的代碼10. 解決Python 進程池Pool中一些坑
