The keyword self is used to refer to the current class itself within the scope of that class only whereas, $this is used to refer to the member variables and function for a particular instance of a class.
self operator: self operator represents the current class and thus is used to access class variables or static variables because these members belongs to a class rather than the object of that class.
New static: The static is a keyword in PHP. Static in PHP 5.3's late static bindings, refers to whatever class in the hierarchy you called the method on. The most common usage of static is for defining static methods.
Late static binding was a feature introduced with php 5.3. It allows us to inherit static methods from a parent class, and to reference the child class being called.
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.
// self
var_dump(Foo::$bar);
// (int) 1234
// static
var_dump(Bar::$bar);
// (int) 4321
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(); // ClassA
echo 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();
As mentioned one of the main differences is that static
allows for late static bindings. One of the most useful scenarios that I found was for creating Base classes for Singleton Classes:
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
Using return static::$name
in the Base class will return what was statically attached when it was extended. If you were to use return self::$name
then B::getName()
would return an empty string as that is what is declared in the Base class.
Maybe this self-explained code helps you:
class Foo { protected static $bar = 'parent value'; public static function test() { var_dump('I am your father'); var_dump('self:: here means '.self::$bar); var_dump('static:: here means '.static::$bar); } } class Bar extends Foo { protected static $bar = 'child value'; public static function test() { parent::Test(); var_dump('I am the child'); var_dump('self:: here means '.self::$bar); var_dump('static:: here means '.static::$bar); } } Bar::test(); Foo::test();
This produces the following output (I have 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With