I know there is a difference between static::
and self::
like in this example ( from https://stackoverflow.com/a/13613718/2342518 )
<?php
class One
{
const TEST = "test1";
function test() { echo static::TEST; }
}
class Two extends One
{
const TEST = "test2";
}
$c = new Two();
$c->test();
Which returns test2 when static::TEST
is used and test1 when self::TEST
is used.
But it also returns test2 when $this::TEST
is used.
static::TEST
can be used inside a static method, whereas $this::TEST
requires an instance before being used (so non-usable in static methods).
But if one cannot use $this::
in static methods, static::
can be used in non-static methods (like in the example).
So, what is the difference between static:: and $this:: in a non static method?
Optional complete test
<?php
abstract class AOne
{
const TEST = "test1";
abstract public function test();
}
class OneStatic extends AOne
{
public function test()
{
return static::TEST;
}
}
class TwoStatic extends OneStatic
{
const TEST = "test2";
}
class OneSelf extends AOne
{
public function test()
{
return self::TEST;
}
}
class TwoSelf extends OneSelf
{
const TEST = "test2";
}
class OneThis extends AOne
{
public function test()
{
return $this::TEST;
}
}
class TwoThis extends OneThis
{
const TEST = "test2";
}
$objects = array(
'one, static::' => new OneStatic(),
'two, static::' => new TwoStatic(),
'one, self::' => new OneSelf(),
'two, self::' => new TwoSelf(),
'one, $this::' => new OneThis(),
'two, $this::' => new TwoThis(),
);
$results = array();
foreach ($objects as $name=>$object)
$results[$name] = $object->test();
var_dump($results);
?>
Which yields
So self refers to the class where the method is defined, but there's no difference between $this::
and static::
in these non static methods.
Static variables are shared among all instances of a class. Non static variables are specific to that instance of a class. Static variable is like a global variable and is available to all methods. Non static variable is like a local variable and they can be accessed through only instance of a class.
The static keyword is used to declare properties and methods of a class as static. Static properties and methods can be used without creating an instance of the class. The static keyword is also used to declare variables in a function which keep their value after the function has ended.
"this" keyword is only applicable where an instance of an object is created. And in static method no instance is created because static method belongs to class area.
No, the "this" keyword cannot be used to refer to the static members of a class. This is because the “this” keyword points to the current object of the class and the static member does not need any object to be called.
There are three cases when you CAN'T use $this::
over static::
1. In static methods
public static function test() {
return $this::MY_CONST;
}
Output:
Fatal error: Uncaught Error: Using $this when not in object context
2. In none-static methods which get called in none-object context
class A {
const MY_CONST = 33;
public function test() {
return $this::MY_CONST;
}
}
echo A::test(); // test method here is called without instantiating class A
Output:
Fatal error: Uncaught Error: Using $this when not in object context
3. When using the special ::class
keyword
class A {
public function test() {
return $this::class;
}
}
$a = new A;
echo $a->test();
Output:
Fatal error: Dynamic class names are not allowed in compile-time
Note: in all the three cases static::
will work
For the last case PHP Documentation states that:
Note:
The class name resolution using ::class is a compile time transformation. That means at the time the class name string is created no autoloading has happened yet. As a consequence, class names are expanded even if the class does not exist. No error is issued in that case.
So you can't use $this::class
because you can't reference to non-existent classes
The behavior in PHP 8 has changed!
For consistency reasons $this::class
now provides the same result as get_class($this)
and static::class
https://3v4l.org/iB99O
There really isn't one. The ::
functionality has been expanded over time, so that the left hand side doesn't need to be a class literal but may also be an object instance or string variable with a class name. Sometime around the same time late static binding was introduced with the static
keyword. As you said, $this
can't be used in static methods, so static
is the obvious and only choice here for late static binding.
In an object instance however you could use static::
to refer to the late-static bound class, which will be the class of the current object instance. Or you could use $this::
as a side effect of being able to use an object instance as shorthand for <class of this object $var>::
. The end result is the same, it's simply functionality which happens to overlap in this particular point. The internal workings are somewhat different, but I can't think of a case where there would ever be any difference.
Just to complete the Venn diagram:
Only static
can do this:
public static function foo() {
static::FOO;
}
Only $var::
can do this:
$obj = new Foo;
$obj::FOO;
Both can do this:
public function foo() {
static::FOO;
$this::FOO;
}
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