Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 684
Farid Rn Avatar asked Sep 05 '25 04:09

Farid Rn


2 Answers

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.

like image 189
user1708452 Avatar answered Sep 07 '25 21:09

user1708452


It makes no difference if your method don't use $this and don't access to static properties.

Static properties cannot be accessed through the object using the arrow operator ->.

$this is not available inside the method declared as static.

But, you should always use :: to call a static method, even through php let you call it on an instance.

like image 22
xdazz Avatar answered Sep 07 '25 19:09

xdazz