深入理解PHP物件導向之後期靜態繫結

arvin-hermit發表於2021-01-17

介紹

自 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 協議》,轉載必須註明作者和本文連結

相關文章