New Self Vs. New Static

New self vs. new static

will I get the same results?

Not really. I don't know of a workaround for PHP 5.2, though.

What is the difference between new self and new static?

self refers to the same class in which the new keyword is actually written.

static, in PHP 5.3's late static bindings, refers to whatever class in the hierarchy you called the method on.

In the following example, B inherits both methods from A. The self invocation is bound to A because it's defined in A's implementation of the first method, whereas static is bound to the called class (also see get_called_class()).

class A {
public static function get_self() {
return new self();
}

public static function get_static() {
return new static();
}
}

class B extends A {}

echo get_class(B::get_self()); // A
echo get_class(B::get_static()); // B
echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A

what means new static?

When you write new self() inside a class's member function, you get an instance of that class. That's the magic of the self keyword.

So:

class Foo
{
public static function baz() {
return new self();
}
}

$x = Foo::baz(); // $x is now a `Foo`

You get a Foo even if the static qualifier you used was for a derived class:

class Bar extends Foo
{
}

$z = Bar::baz(); // $z is now a `Foo`

If you want to enable polymorphism (in a sense), and have PHP take notice of the qualifier you used, you can swap the self keyword for the static keyword:

class Foo
{
public static function baz() {
return new static();
}
}

class Bar extends Foo
{
}

$wow = Bar::baz(); // $wow is now a `Bar`, even though `baz()` is in base `Foo`

This is made possible by the PHP feature known as late static binding; don't confuse it for other, more conventional uses of the keyword static.

Why return new static? (PHP)

new static instantiates a new object from the current class, and works with late static bindings (instantiates the subclass if the class was subclassed, I expect you understand that).

Having a static method on a class which returns a new instance of same is an alternative constructor. Meaning, typically your constructor is public function __construct, and typically it requires a certain bunch of parameters:

class Foo {
public function __construct(BarInterface $bar, array $baz = []) { ... }
}

Having an alternative constructor allows you to provide different defaults, or convenience shortcuts to instantiate this class without having to supply those specific arguments and/or for being able to provide different arguments which the alternative constructor will convert to the canonical ones:

class Foo {

public function __construct(BarInterface $bar, array $baz = []) { ... }

public static function fromBarString($bar) {
return new static(new Bar($bar));
}

public static function getDefault() {
return new static(new Bar('baz'), [42]);
}

}

Now, even though your canonical constructor requires a bunch of complex arguments, you can create a default instance of your class, which will probably be fine for most uses, simply with Foo::getDefault().

The canonical example in PHP for this is DateTime and DateTime::createFromFormat.

In your concrete example the alternative constructor doesn't actually do anything, so it's rather superfluous, but I expect that's because it's an incomplete example. If there's indeed an alternative constructor which does nothing other than new static, it's probably just meant as convenience syntax over (new Foo)->, which I find questionable.

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.

// 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.

What does construction new static() mean in symfony?

From this answer

When you write new self() inside a class's member function, you get an instance of that class. That's the magic of the self keyword.

    So:

class Foo
{
public static function baz() {
return new self();
}
}

$x = Foo::baz(); // $x is now a `Foo`

You get a Foo even if the static qualifier you used was for a derived class:

class Bar extends Foo
{
}

$z = Bar::baz(); // $z is now a `Foo`

If you want to enable polymorphism (in a sense), and have PHP take notice of the qualifier you used, you can swap the self keyword for the static keyword:

class Foo
{
public static function baz() {
return new static();
}
}

class Bar extends Foo
{
}

$wow = Bar::baz(); // $wow is now a `Bar`, even though `baz()` is in base `Foo`

This is made possible by the PHP feature known as late static binding; don't confuse it for other, more conventional uses of the keyword static.



Related Topics



Leave a reply



Submit