phpfactorydryselflate-static-binding

How to make 'self' in parent class refer to extended class in PHP?


I'm working with Wordpress and need to instantiate a new class similar to this oversimplified example (for an add_action() hook which receives some arguments):

class A {
        public function __construct() {
        }

        public static function init() {
                $instance = new self();
                $instance->doStuff();
        }

        protected function doStuff() {
                echo get_class($this);
        }
}

class B extends A {
}

B::init(); //returns 'A'

How can I get self in init() to refer to extended classes when called from them? I'm aware of the late static bindings page in the PHP docs, but I'm not clear on how to apply it in the above context. Thanks!


Solution

  • public static function init() {
        $instance = new static();
        $instance->doStuff();
    }
    

    You can see this working on 3v4l, which is a great place to sandbox some PHP.

    Why static? You were right to look at the PHP manual for late static bindings, and it's a shame the page doesn't explicitly mention this specific use of the static keyword (though, there's a comment that does).

    In the context of late static bindings, you can replace self with static, and it will use the instantiated class, whereas self would use the class the code lives in. For example:

    <?php
    class A {
    
    }
    
    class B extends A {
        public function test() {
            echo parent::class;
            echo self::class;
            echo static::class;
        }
    }
    class C extends B {
    
    }
    
    $c = new C();
    $c->test();
    

    This even works in a static context (unfortunately, the static keyword is used in two different contexts: static calls, and late static binding), as per my example above.