29

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?

5
  • Is my question that much not-useful which I deserve to have -1? Commented Oct 19, 2012 at 19:21
  • 2
    as people say "He that nothing questioneth, nothing learneth" (question is quite basic but I dont see any reason why you got -1) +1 Commented Jan 18, 2013 at 22:09
  • 3
    Why is this question considered to be so basic? I've been doing this for years and I had no clear thought about whether this is bad practice or not, which is what brought me here. This is an excellent question. Commented Jun 6, 2016 at 10:26
  • @OCDev the question is quiet old, but thank you. :) Commented Jun 7, 2016 at 10:24
  • 2
    Timeless questions like this don't get old to those who haven't seen the answer yet. Thank you again for asking it! Commented Jun 7, 2016 at 22:34

3 Answers 3

19

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Your answer deserves to be the accepted answer because of complete explanation and examples. BTW about your last line I think it's not possible to always not use static methods because sometimes the best solution is to use static methods. It saves a lot of code and makes the application simpler and more editable. I can show you too many examples if you want to. Anyway, thanks for your complete answer.
Thank you! Yes, i too am aware of situations where static functions are quite convenient, but i still prefer a higher grade of testability over the benefits of static. My remark on that topic was only intended to (at least) provoke a conscious thought about this potentially problematic side-effect of static.
Wrong. No error or warning is generated for calling static methods with the arrow operator.
Worth noting that you can call $test::doSomthing() as well, which seems correct and has advantages.
4

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.

Comments

3

It is better you call it this way to avoid E_STRICT on some version of PHP

$bar = test::doSomething('Sandwich');

FROM PHP DOC

Static properties cannot be accessed through the object using the arrow operator ->. Calling non-static methods statically generates an E_STRICT level warning.

Also

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.