What is Call Forwarding and Static Calls in PHP or

2019-05-13 23:23发布

问题:

One code sample I have got from a website, but it was difficult for me to understand the output. I am sharing the code :

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();

The Output is as follows ::

A
C
C

I would be highly helped if the above output is explained. Thanks in Advance.

回答1:

One code sample I have got from a website, but it was difficult for me to understand the output. I am sharing the code

This code is an exact replica from the PHP Manual of the Late Static Binding concept..

Explanation of this code from the manual..

Late static bindings' resolution will stop at a fully resolved static call with no fallback. On the other hand, static calls using keywords like parent:: or self:: will forward the calling information.

Source

So let me explain in depth...

When you do .. C::test(); , The test() under the class B will be called as there is no test() available on class C.

So you are obviously here..

   public static function test() 
   {
      A::foo();
      parent::foo();
      self::foo();
   }

Case 1 : A::foo();

As you read this from the above statement.. Late static bindings' resolution will stop at a fully resolved static call with no fallback , so since it is a fully resolved static call , you will get an output of A

Case 2 & 3 : parent::foo(); and self::foo();

Again, from the above statement.. static calls using keywords like parent:: or self:: will forward the calling information.

So this will obviously print C and C .. because since you did C::test(); , The class C is the actual caller.