介紹
自 PHP 5.3.0 起,PHP 增加了一個叫做後期靜態繫結的功能,用於在繼承範圍內引用靜態呼叫的類。
準確說,後期靜態繫結工作原理是儲存了在上一個“非轉發呼叫”(non-forwarding call)的類名。當進行靜態方法呼叫時,該類名即為明確指定的那個(通常在 :: 運算子左側部分);當進行非靜態方法呼叫時,即為該物件所屬的類。所謂的“轉發呼叫”(forwarding call)指的是通過以下幾種方式進行的靜態呼叫:self::
,parent::
,static::
以及 forward_static_call()
。可用 get_called_class()
函式來得到被呼叫的方法所在的類名,static:: 則指出了其範圍。
轉發呼叫&非轉發呼叫
轉發呼叫
所謂的轉發呼叫是指:在類的方法呼叫中轉發呼叫資訊
(可以理解為呼叫棧資訊)
轉發呼叫的時機
parent呼叫
self呼叫
static呼叫
forward_static_call()
非轉發呼叫
所謂的非轉發呼叫是指:是明確的指定靜態呼叫的類名或通過物件(偽物件)例項的呼叫
程式碼解析
<?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();
後期靜態繫結
該功能從語言內部角度考慮被命名為“後期靜態繫結”。“後期繫結”的意思是說,static:: 不再被解析為定義當前方法所在的類,而是在實際執行時計算的。也可以稱之為“靜態繫結”,因為它可以用於(但不限於)靜態方法的呼叫。
後期靜態繫結實現原理
後期靜態繫結工作原理是儲存了在上一個“非轉發呼叫”(non-forwarding call)的類名。
這句話的意思就是在程式執行過程中到底如何確認static是哪個類,確定規則是取上次儲存的非轉發呼叫的類後期靜態繫結應用
單例繼承場景
抽象類和實現類
本作品採用《CC 協議》,轉載必須註明作者和本文連結