phplate-static-binding

Can I use Late Static Binding for non-static members?


The documentation says that:

This feature was named "late static bindings" with an internal perspective in mind. "Late binding" comes from the fact that static:: will not be resolved using the class where the method is defined but it will rather be computed using runtime information. It was also called a "static binding" as it can be used for (but is not limited to) static method calls.

What does it mean by "not limited to static methods only"?

I'm just trying to understand that, I don't want to do something concrete, an example would be nice, for example.


Solution

  • The place I most commonly use it is when you want to override a constant in an inheriting class, but it's used in a method that's not also overridden in the inheriting class:

    class A
    {
        const FOO = 'A';
        public function foo()
        {
            printf("I am: %s\n", get_class($this));
            printf("self::FOO = %s\n", self::FOO);
            printf("static::FOO = %s\n", static::FOO);
            echo "\n";
        }
    }
    
    class B extends A
    {
        const FOO = 'B';
    }
    

    Here, if we run the inherited method that uses self::, we'll get the value that's defined in the parent class, not the instantiated class. I.e., inside the B class, self::FOO has a value of A if it's referred to by a method inherited from A. So self:: will give us the class where the method is defined, and static:: will give us the class we happen to be in at runtime.

    (new A())->foo();
    (new B())->foo();
    

    Outputs:

    I am: A
    self::FOO = A
    static::FOO = A
    
    I am: B
    self::FOO = A
    static::FOO = B
    

    So this is not a static method call, but we're still using the static:: keyword to make sure we get the overriding value, if any.