Problem
In the example below, what is the difference between using self and static?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
1234
1234
Asked by cwd
Solution #1
When you refer to a class member with the keyword self, you’re referring to the class in which the keyword is used. Your Foo class defines a protected static property called $bar in this scenario. When you use self to refer to a property in the Foo class, you’re referring to the same class.
If you tried to use self::$bar elsewhere in your Foo class but had a Bar class with a different value for the property, it would instead use Foo::$bar instead of Bar::$bar, which may not be what you intended:
class Foo
{
protected static $bar = 1234;
}
class Bar extends Foo
{
protected static $bar = 4321;
}
When you use static to invoke a method, you’re using a feature called late static bindings (introduced in PHP 5.3).
Using self in the aforementioned scenario will result in Foo::$bar (1234). Because the interpreter takes into consideration the redeclaration within the Bar class during runtime while using static, the output is Bar::$bar (4321).
// self
var_dump(Foo::$bar);
// (int) 1234
// static
var_dump(Bar::$bar);
// (int) 4321
Because you don’t commonly redeclare properties in subclasses, you usually use late static bindings for methods or even the class itself, rather than properties; an example of utilizing the static keyword for invoking a late-bound constructor can be found in this linked question: The new self vs the new static
That isn’t to say that you can’t use static with properties.
Answered by BoltClock
Solution #2
I’ve included a simple example to demonstrate the difference between self and static. Static:: is used to perform Late Static Binding, which binds the variable value from the child class.
class A { // Base Class
protected static $name = 'ClassA';
public static function getSelfName() {
return self::$name;
}
public static function getStaticName() {
return static::$name;
}
}
class B extends A {
protected static $name = 'ClassB';
}
echo B::getSelfName(); // ClassA
echo B::getStaticName(); // ClassB
Answered by Jsowa
Solution #3
With self call:
class Phone
{
protected static $number = 123;
public function getNumber()
{
return self::$number;
}
}
class Fax extends Phone
{
protected static $number = 234;
}
// Displays: "123"
echo (new Fax)->getNumber();
Because we specifically asked PHP for the self variable, which in turn asks for the Phones variable instead, even though we have overridden the $number with our Fax class, it still returns 123.
If we replace the self call with static, we get the following Faxs overridden value:
With static call:
class Phone
{
protected static $number = 123;
public function getNumber()
{
return static::$number;
}
}
class Fax extends Phone
{
protected static $number = 234;
}
// Displays: "234"
echo (new Fax)->getVar();
Answered by Steve Bauman
Solution #4
One of the primary differences, as previously stated, is that static allows for late static bindings. Creating Base Classes for Singleton Classes was one of the most useful scenarios I discovered:
class A { // Base Class
protected static $name = '';
protected static function getName() {
return static::$name;
}
}
class B extends A {
protected static $name = 'MyCustomNameB';
}
class C extends A {
protected static $name = 'MyCustomNameC';
}
echo B::getName(); // MyCustomNameB
echo C::getName(); // MyCustomNameC
Returning what was statically connected when the Base class was extended using return static::$name in the Base class. If you use return self::$name, B::getName() will return an empty string because that is what the Base class declares.
Answered by ggedde
Solution #5
Perhaps this self-explanatory code will be useful:
The following is the result (I’ve added Line Breaks for clarity):
'I am your father' (length=16)
'self:: here means parent value' (length=30)
'static:: here means child value' (length=31)
'I am the child' (length=14)
'self:: here means child value' (length=29)
'static:: here means child value' (length=31)
'I am your father' (length=16)
'self:: here means parent value' (length=30)
'static:: here means parent value' (length=32)
Answered by dwoutsourcing
Post is based on https://stackoverflow.com/questions/11710099/what-is-the-difference-between-selfbar-and-staticbar-in-php