What is the difference between self::$bar and static::$bar in PHP?
When you use self
to refer to a class member, you're referring to the class within which you use the keyword. In this case, your Foo
class defines a protected static property called $bar
. When you use self
in the Foo
class to refer to the property, you're referencing the same class.
Therefore if you tried to use self::$bar
elsewhere in your Foo
class but you had a Bar
class with a different value for the property, it would use Foo::$bar
instead of Bar::$bar
, which may not be what you intend:
class Foo{ protected static $bar = 1234;}class Bar extends Foo{ protected static $bar = 4321;}
When you call a method via static
, you're invoking a feature called late static bindings (introduced in PHP 5.3).
In the above scenario, using self
will result in Foo::$bar
(1234).And using static
will result in Bar::$bar
(4321) because with static
, the interpreter takes into account the redeclaration within the Bar
class during runtime.
You typically use late static bindings for methods or even the class itself, rather than properties, as you don't often redeclare properties in subclasses; an example of using the static
keyword for invoking a late-bound constructor can be found in this related question: New self vs. new static
However, that doesn't preclude using static
with properties as well.
I have small example showing difference between self
and static
. Using static::
performs Late Static Binding and thus it binds the variable value from 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(); // ClassAecho B::getStaticName(); // ClassB
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();
You can see above, even though we have overridden the $number
with our Fax
class, it still returns 123
, because we have explicitly asked PHP for the self
variable, which in turn asks for Phone
s variable instead.
Now if we swap the self
call with static
, we will instead get Fax
s 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();