Coder Perfect

What is the difference between self::$bar and static::$bar in PHP?

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