14
class t {
    public function tt()
    {
        echo 1;
    }
}
t::tt();

See?The non-static function can also be called at class level.So what's different if I add a static keyword before public?

user198729
  • 61,774
  • 108
  • 250
  • 348

6 Answers6

15

Except that, if you try to use $this in your method, like this :

class t {
    protected $a = 10;
    public function tt() {
        echo $this->a;
        echo 1;
    }
}
t::tt();

You'll get a Fatal Error when calling the non-static method statically :

Fatal error: Using $this when not in object context in ...\temp.php on line 11

i.e. your example is a bit too simple, and doesn't really correspond to a real-case ;-)


Also note that your example should get you a strict warning (quoting) :

Calling non-static methods statically generates an E_STRICT level warning.

And it actually does (At least, with PHP 5.3) :

Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12
1

So : not that good ;-)


Still, statically calling a non-static method doesnt't look like any kind of good practice (which is probably why it raises a Strict warning), as static methods don't have the same meaning than non-static ones : static methods do not reference any object, while non-static methods work on the instance of the class there're called on.


Once again : even if PHP allows you to do something (Maybe for historical reasons -- like compatibility with old versions), it doesn't mean you should do it !

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • I didn't get a strict warning,php.ini setting is `error_reporting = E_ALL` – user198729 Mar 13 '10 at 16:32
  • 3
    @user : this is because `E_ALL` doesn't include `E_STRICT` -- see http://www.php.net/manual/en/errorfunc.constants.php which states that `E_ALL` is *"All errors and warnings, as supported, except of level `E_STRICT` in PHP < 6"* – Pascal MARTIN Mar 13 '10 at 16:34
  • Oh,I've changed to `error_reporting = E_ALL & E_STRICT`,still no warning..PHP5.3.0 – user198729 Mar 13 '10 at 16:36
  • 2
    That's probably because you don't need to use `E_ALL & E_STRICT`, but `E_ALL | E_STRICT` *(i.e you need `E_ALL` + `E_STRICT`)* -- and not sure about in which version of PHP this started to raise an `E_STRICT` – Pascal MARTIN Mar 13 '10 at 16:39
  • The `not in object context` error is at least obvious. When you *are* in an object context (some instance method of some object belonging to a totaly different class) when issuing `t::tt()`, `$this` will refer to that object, without any warning. – Tgr Mar 17 '11 at 15:29
  • "non-static methods work on the instance of the class there're called on." Well apparently not. Or the examples in this thread wouldn't work. – robomc Aug 20 '12 at 21:55
  • -1 - This answer does not properly explain the critical functional difference and falsely suggests that calling a non-static method in static context will result in a fatal error. The critical difference is that **static methods do not have access to `$this`** (even if invoked via an instance object). You will only get a fatal error if you attempt to access `$this` when it is undefined. (You can test for its availability with `isset()` and `empty()`.) – danorton Mar 25 '14 at 19:06
4

The Static Keyword

Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static.

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

Calling non-static methods statically generates an E_STRICT level warning.

Just because you can call non-static methods statically doesn't mean you should. It's bad form.

Community
  • 1
  • 1
jasonbar
  • 13,333
  • 4
  • 38
  • 46
2

In general a static method is also called class method while a non-static method is also called object method or instance method.

The difference between a class method and an object method is that class methods can only access class properties (static properties) while object methods are used to access object properties (properties of the very same class instance).

Static methods and properties are used to share common data over or for all instances of that specific class.

You could, for example, use a static property to keep track of the number of instances:

class A {
    private static $counter = 0;

    public function __construct() {
        self::counter = self::counter + 1;
    }

    public function __destruct() {
        self::counter = self::counter - 1;
    }

    public static function printCounter() {
        echo "There are currently ".self::counter." instances of ".__CLASS__;
    }
}

$a1 = new A();
$a2 = new A();
A::printCounter();
unset($a2);
A::printCounter();

Note that the static property counter is private so it can only be accessed by the class itself and instances of that class but not from outside.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
1

A main difference that has not been mentioned relates to polymorphic behavior.

Non static methods, when redeclared in a derived class, override the base class method, and allow polymorphic behavior based on the type of the instance they are called on. This is not the case for static methods.


PHP 5.3 introduced the concept of late static binding which can be used to reference the called class in a context of static inheritance.

JRL
  • 76,767
  • 18
  • 98
  • 146
0

Yes, the critical difference is that methods declared static do not have access to the object-context variable, $this.

Additionally, invocation of a non-static method when not in object context will trigger an E_STRICT error event. When enabled, that event’s default behavior is to output a message to the error log (or STDERR), but it will allow the program to continue running.

Also, any attempt to reference $this when not in an object context will trigger an E_ERROR event. That event’s behavior is to output a message to the error log (or STDERR) and to exit the program with status 255.

For example:

<?php
error_reporting(-1);
//error_reporting(E_ALL);

class DualNature {
  public static function fnStatic() {
    if ( isset( $this ) ) {
      // never ever gets here
      $myValue = $this->_instanceValue;
    } else {
      // always gets here
      $myValue = self::$_staticValue;
    }
    return $myValue;
  }

  public function fnInstance() {
    if ( isset( $this ) ) {
      // gets here on instance (->) reference only
      $myValue = $this->_instanceValue;
    } else {
      // gets here in all other situations
      $myValue = self::$_staticValue;
    }
    return $myValue;
  }

  public static function fnStaticDeath() {
    return $this->_instanceValue;
  }

  private static $_staticValue = 'no access to $this';
  private $_instanceValue = '$this is available';

}

$thing = new DualNature();
echo "==========\n";
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic() );
echo "==========\n";
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic() );
echo "==========\n";
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic() );
echo "==========\n";
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance() );
echo "==========\n";
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance() );
echo "==========\n";
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance() );
echo "==========\n";
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath() );
echo "==========\n";
echo "I'M ALIVE!!!\n";

The output of the above is:

==========
PHP Strict Standards:  Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45
DualNature::fnStatic(): "no access to $this"
==========
$thing::fnStatic(): "no access to $this"
==========
$thing->fnStatic(): "no access to $this"
PHP Strict Standards:  Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47
==========
DualNature::fnInstance(): "no access to $this"
==========
$thing::fnInstance(): "no access to $this"
==========
$thing->fnInstance(): "$this is available"
==========
PHP Fatal error:  Using $this when not in object context in example.php on line 29

Changing the error reporting level to E_ALL will suppress the default E_STRICT warning messages (the event will still be propagated), but the invalid reference to $this will still cause a fatal error and will exit the program.

danorton
  • 11,804
  • 7
  • 44
  • 52
0

Besides the syntax and functional differences there is also a performance difference that matters.

You can refer to this more or less detailed comparison of static and non-static methods in PHP.

Stanislav
  • 903
  • 2
  • 9
  • 14