27

Why in PHP you can access static method via instance of some class but not only via type name?

UPDATE: I'm .net developer but i work with php developers too. Recently i've found this moment about static methods called from instance and can't understand why it can be usefull.

EXAMPLE:

class Foo
{
    public static Bar()
    {
    }
}

We can accept method like this:

var $foo = new Foo();
$foo.Bar(); // ??????
Matthew Lock
  • 13,144
  • 12
  • 92
  • 130
donRumatta
  • 836
  • 2
  • 9
  • 22
  • 6
    Static methods and properties are a little tricky at first. All you need to remember is that a static method or property is one that can be used without instantiating the object first. – EGHDK Feb 09 '12 at 07:12
  • Can you clarify what exactly you mean with a code snippet? Your question is somewhat ambiguous. – deceze Feb 09 '12 at 07:28
  • This is not PHP-specific. In Python you can also access methods decorated with `@staticmethod` decorators from the instance, and the only difference is that static methods do not receive the context (object) in which they are called. – Tadeck Feb 09 '12 at 07:44

5 Answers5

40

In PHP

the class is instantiated using the new keyword for example;

$MyClass = new MyClass();

and the static method or properties can be accessed by using either scope resolution operator or object reference operator. For example, if the class MyClass contains the static method Foo() then you can access it by either way.

$MyClass->Foo();

Or

MyClass::Foo()

The only rule is that static methods or properties are out of object context. For example, you cannot use $this inside of a static method.

wp78de
  • 18,207
  • 7
  • 43
  • 71
Ibrahim Azhar Armar
  • 25,288
  • 35
  • 131
  • 207
  • 1
    Although using instance it also works: `$class->staticMethod()` – dmitry Feb 09 '12 at 07:25
  • 9
    @Ibrahim - Actually, that's incorrect. You can access both static and non-static methods from either an instance of the class or the class itself. The only time you'll get an error is when you call a method that refers to `$this` statically. – Sam Dufel Feb 09 '12 at 07:29
  • As of PHP 7 calling non-static methods statically has been deprecated and may be removed – Omn Jan 16 '20 at 15:58
15
Class Do {
  static public function test() {
      return 0;
  }
}

use like this :

echo Do::test();
Milap
  • 6,915
  • 8
  • 26
  • 46
Said Afkir
  • 161
  • 1
  • 5
7

Why in PHP you can access static method via instance of some class but not only via type name?

Unlike what you are probably used to with .NET, PHP has dynamic types. Consider:

class Foo
{
  static public function staticMethod() { }
}

class Bar
{
  static public function staticMethod() { }
}

function doSomething($obj)
{
  // What type is $obj? We don't care.
  $obj->staticMethod();
}

doSomething(new Foo());
doSomething(new Bar());

So by allowing access to static methods via the object instance, you can more easily call a static function of the same name across different types.

Now I don't know if there is a good reason why accessing the static method via -> is allowed. PHP (5.3?) also supports:

$obj::staticMethod();

which is perhaps less confusing. When using ::, it must be a static function to avoid warnings (unlike ->, which permits either).

Matthew
  • 47,584
  • 11
  • 86
  • 98
  • perhaps non static methods with an interface should be used in your example, because such using of static methods is a bit confusing, isn't it? – donRumatta Feb 09 '12 at 10:21
  • @donRumatta, I wouldn't claim that the above is good code. But due to PHP's dynamic features, interfaces aren't strictly necessary, and many people code without them. Note that PHP didn't always have good OOP support, so some of the answers to "why" are just "bad design decisions of past versions." – Matthew Feb 09 '12 at 16:26
  • Using -> for statics is deprecated on PHP 7. – Samuel Åslund Sep 05 '18 at 15:08
  • 1
    @SamuelÅslund I think you have that backwards, it is using `::` to call non-statics that is deprecated: https://www.php.net/manual/en/language.oop5.static.php – Omn Jan 16 '20 at 15:56
  • @Omn *Static properties cannot be accessed through the object using the arrow operator ->* - from [here](https://www.php.net/manual/en/language.oop5.static.php). – Hashim Aziz Jan 17 '21 at 00:17
2

In PHP, while you're allowed to access the static method by referencing an instance of the class, you don't necessarily need to do so. For example, here is a class with a static function:

class MyClass{
    public static function  MyFunction($param){
        $mynumber=param*2;
        return $mynumber;
}

You can access the static method just by the type name like this, but in this case you have to use the double colon (::), instead of "->".

$result= MyClass::MyFunction(2);

(Please note you can also access the static method via an instance of the class as well using "-->"). For more information: http://php.net/manual/en/language.oop5.static.php

0

In PHP 7 it seems to be absolutely necessary for you to be able to do $this->staticFunction(). Because, if this code is written within an abstract class and staticFunction() is also abstract in your abstract class, $this-> and self:: deliver different results!

When executing $this->staticFunction() from a (non-abstract) child of the abstract class, you end up in child::staticFunction(). All is well.

However, executing self::staticFunction() from a (non-abstract) child of the abstract class, you end up in parent::staticFunction(), which is abstract, and thusly throws an exception.

I guess this is just another example of badly designed PHP. Or myself needing more coffee...

ryh
  • 19
  • 2
  • 2
    I guess this is just another example of badly educated developers,.. RTFM using $this while accessing static methods is NEVER a good idea neighter required. If you would read the docs you would know that in this case (among others) you can chose between parent and child class by using either "self::" or "static::" see http://php.net/manual/en/language.oop5.late-static-bindings.php By that inheritance on static methods might not be the best strategy after all. – Flip Vernooij Mar 23 '19 at 18:03