PHP: What if I call a static method in non-static way

Farid Rn picture Farid Rn · Oct 13, 2012 · Viewed 7.4k times · Source

I'm not pro in Object Oriented Programming and I got a silly question:

class test {
    public static function doSomething($arg) {
        $foo = 'I ate your ' . $arg;
        return $foo;
    }
}

So the correct way to call doSomething() method is to do test::doSomething('Pizza');, Am I right?

Now, what will happen if I call it like this:

$test = new test;
$bar = $test->doSomething('Sandwich');

I've tested it and it's working without any error or notice or etc. but is that correct to do this?

Answer

user1708452 picture user1708452 · Oct 13, 2012

As Baba already pointed out, it results in an E_STRICT depending on your configuration.

But even if that's no problem for you, I think it's worth mentioning some of the pitfalls which may result from calling static methods in a non-static way.

If you have a class hierarchy like

class A {
    public static function sayHello() {
        echo "Hello from A!\n";
    }

    public function sayHelloNonStaticWithSelf() {
        return self::sayHello();
    }

    public function sayHelloNonStaticWithStatic() {
        return static::sayHello();
    }
}

class B extends A {
    public static function sayHello() {
        echo "Hello from B!\n";
    }

    public function callHelloInMultipleDifferentWays() {
        A::sayHello();
        B::sayHello();
        $this->sayHelloNonStaticWithSelf();
        $this->sayHelloNonStaticWithStatic();
        $this->sayHello();
    }
}

$b = new B();
$b->callHelloInMultipleDifferentWays();

This produces the following output:

Hello from A!
// A::sayHello() - obvious

Hello from B!
// B::sayHello() - obvious

Hello from A!
// $this->sayHelloNonStaticWithSelf()
// self alweays refers to the class it is used in

Hello from B!
// $this->sayHelloNonStaticWithStatic()
// static always refers to the class it is called from at runtime

Hello from B!
// $this->sayHello() - obvious

As you can see, it's easy to achieve unexpected behaviour when mixing static and non-static method calls and techniques.

Therefore, my advice also is: Use Class::method to explicitly call the static method you mean to call. Or even better don't use static methods at all because they make your code untestable.