class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
// echo (new self)->a;
}
}
class B extends A {
public static function fun2() {
return (new self)->fun1();
// return static::fun1();
}
}
B::fun2(); // returns BooMBa
If I change fun2() to return static::fun1()
then it gives
'Fatal Error: Using $this when not in object context'But if I change fun1 to
echo (new self)->a;
then works fine.static::
hate $this
but not (new self)
.PPS: This Q&A PHP Fatal error: Using $this when not in object context has nothing to do with mine other than the same error message. It's totally different context. In that question he simply calls a non-static method statically. Meanwhile my question is more complex with late static bindings and keywords (new self). It's not possible at all to understand my problem with the answer in the above mentioned Q&A so please go through both Q&A before marking it duplicate. Thank you.
This questions comes to "what is difference between class and instance".
I will simplify your example and go step by step.
class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
}
public static function fun2() {
return (new self)->fun1();
}
}
A::fun2(); // returns BooMBa
A::func2()
- static call to A::func2
(new self)->fun1()
- creates instance of A
and calls fun1
of that instanceecho $this->a
- echo contents of a
of current(created in step 2) instanceEvery call to A::func2
creates new instance of A
in step 2
class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
}
public static function fun2() {
return static::fun1();
}
}
A::fun2(); // fails
A::func2()
- static call to A::func2
static::fun1()
- static call to A::func1
, there is no instance. AFAIK this should generate warning since you make static call to instance methodecho $this->a;
- echo contents of a
of current instance, but there is no instance since we came here from static call, we are in class scope. Errorclass A {
public $a = "BooMBa";
public function fun1() {
echo (new self)->a;
}
public static function fun2() {
return static::fun1();
}
}
A::fun2(); // returns BooMBa
A::func2()
- static call to A::func2
static::fun1()
- static call to A::func1
, there is no instanceecho (new self)->a
- create new instance of A
and echo contents of variable a
of just created instanceEvery call to A::func2
creates new instance of A
in step 3
class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
}
public function fun2() {
return $this->fun1();
}
}
$a = new A();
$a->fun2(); // returns BooMBa
$a = new A()
- create new instance of A
$a->fun2()
- call method fun2
of instance $a
$this->fun1()
- call method fun1
of current instance ($a
)echo $this->a
- echo contents of a
of current instance ($a
)$this
refers to current instance of class, but if you static
call, there is no instance. new self
creates new instance of class which allows you to use $this
since you have instance to refer to
Let's make example on cats. Instance of Cat
is some $cat
that stands in front of you. You can ask your $cat
to purrr
and since you refer to concrete instance of cat, inside of method purrr
of that cat you can refer to $this
and call echo $this->purrrSound
. When you make static call you make call to abstract concept of Cat
, there is no particular instance of Cat
and there is no $this
to refer to.
class Cat {
public $purrrSound = "purrrrr...";
public function purrr() {
echo $this->purrrSound;
}
}
$cat = new Cat();
$cat->purrr(); // kittty purrrr, please?
// Cat::purrr(); // all the Cats in the universe, purrr now?
In PHP you can call method statically with The Scope Resolution Operator operator ::
. So, this expression is just a static call:
return static::fun1()
When you're in a static context (after static call) $this
doesn't work - it's a language assertion. Even in a static context this expression is still valid:
(new self)->a
Just because you're creting a new instance of object and then getting it's public property.
Caution In PHP 5, calling non-static methods statically generates an E_STRICT level warning.
Warning In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.
To your consideration:
Consider not to use static methods, because it's a coupling for other classes, and it's usually just a procedural code closes in a static method. For example implement this function in a new class and use dependency injection if you need it.