Kolyunya
Kolyunya

Reputation: 6240

Invoking a non-static method via the scope resolution operator

I've found some strange (for me) behavior of the PHP interpreter and I'm not sure if it's safe to use it in production or not.

When we call Foo::bar() and the Foo class does not have the static bar method but it has non-static bar method, the interpreter will invoke non-static bar on null (yes, it sounds ridiculous). I expected the __callStatic to be invoked in this case. But it's not what is happening for some reason.

I've then found a handy usage for this behavior: to provide the class with static and non-static methods with the same name like this:

class Foo
{
    public function bar(){
        if (isset($this)) {
            $this->nonStaticBar();
        } else {
            static::staticBar();
        }
    }

    private function nonStaticBar() {
        echo "Non-static\n";
    }

    private static function staticBar() {
        echo "Static\n";
    }
}

(new Foo())->bar(); // Output: "Non-static"
Foo::bar(); // Output: "Static"

Yes I know, that this approach is not elegant and architecturally wrong. The question is if it's safe (standard-compliant) to use this "feature" or not. Are there any other cases when isset($this) can equal false?

Upvotes: 6

Views: 719

Answers (1)

C.Liddell
C.Liddell

Reputation: 1082

While your above example does work, it is not best practice. This is recognized in the PHP documentation here and states that in PHP versions before version 7, if E_STRICT error reporting is enabled then it will emit the error:

Strict Standards: Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22

Additionally in PHP versions 7 and above calling static functions statically is deprecated and will cause the following error upon execution:

Deprecated:  Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22

Upvotes: 3

Related Questions