Question

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?

Was it helpful?

Solution

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 !

OTHER TIPS

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.

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.

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.

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top