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
andnew 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
Strange Behavior of Foreach When Using Reference: Foreach ($A as &$V) { ... }
How to Filter an Array by a Condition
PHP MySQLi_Connect: Authentication Method Unknown to the Client [Caching_Sha2_Password]
How to Create a Secure MySQL Prepared Statement in PHP
How to List Has Same Id Data With While Loop in PHP
MySQL and Nosql: Help Me to Choose the Right One
Sort Multidimensional Array by Multiple Columns
Do Htmlspecialchars and MySQL_Real_Escape_String Keep My PHP Code Safe from Injection
Convert Base64 String to an Image File
Forcing to Download a File Using PHP
How to Find Where I Will Be Redirected Using Curl in PHP
Warning: a Non-Numeric Value Encountered
Is There a Function to Extract a 'Column' from an Array in PHP