Home » Php » class – PHP Calling self on a non-static method

class – PHP Calling self on a non-static method

Posted by: admin July 12, 2020 Leave a comment

Questions:

Why is the ‘self’-call to a non-satic method in this example working?

class A{

    protected function aNonStaticMethod(){
        return __class__;
    }

    public function aEcho(){
        echo self::aNonStaticMethod();
    }
}

Thanks for explanation.

How to&Answers:

Calling non-static method statically

Theoretically it should not work, but as this comment says:

There was no static keyword in php4 but php4 did allow for static
calls. To maintain backwards compatibility this was left in when the
static keyword was added in php5.

This comment is supported by this official php.net wiki:

This is already deprecated if the call occurs from an instance method.
Not annotating methods as static is an obsolete PHP4-ism.

You really should not call non-static method statically – it does not make sense (if there is a static keyword).

Avoid calling non-static methods statically completely!

…because a) it is a bad approach and b) the PHP docs say:

Caution

In PHP 5, calling non-static methods statically generates an E_STRICT level warning.

AND

Warning

In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.

Using :: operator for non-static calls – may be a good approach!

As @Kontrollfreak pointed out and as this docs say the :: operator is not limited to static calls:

the double colon, is a token that allows access to static, constant,
and overridden properties or methods of a class

So it is OK if you reference this way a method or properties from a parent class – which is not limited to a direct parent.

EDIT: do not mistake this for Fascade etc. software patterns!

During writing this answer I forgot to mention that there might be cases, when the call is static, but internally it is calling dynamic method – for more info see patterns like Facade or Singleton.

However do NOT mistake these with issue described above! (issue above is about using direct static call on dynamic thing that should be called dynamically, these patterns are about calling static methods statically, which then may dynamically invoke something dynamic (internally)).

Answer:

In your simple example $this and self is interchangable. But be aware of the different method resolving when dealing with inheritance (i added static for completeness):

class A {
    protected function aNonStaticMethod(){
        return __class__;
    }

    public function selfEcho(){
        echo self::aNonStaticMethod();
    }

    public function staticEcho(){
        echo static::aNonStaticMethod();
    }

    public function thisEcho(){
        echo $this->aNonStaticMethod();
    }
}

class B extends A {
    protected function aNonStaticMethod(){
        return __class__;
    }
}

$b = new B();
$b->selfEcho(); // A
$b->staticEcho(); // B
$b->thisEcho(); // B