Reputation: 31
I recently read about calling scope and scope resolution operator (::) in PHP. There are two variations: instance calling and statical calling. Consider the folowing listeng:
<?php
class A {
public function __call($method, $parameters) {
echo "I'm the __call() magic method".PHP_EOL;
}
public static function __callStatic($method, $parameters) {
echo "I'm the __callStatic() magic method".PHP_EOL;
}
}
class B extends A {
public function bar() {
A::foo();
}
}
class C {
public function bar() {
A::foo();
}
}
A::foo();
(new A)->foo();
B::bar();
(new B)->bar();
C::bar();
(new C)->bar();
The result of execution (PHP 5.4.9-4ubuntu2.2) is:
I'm the __callStatic() magic method
I'm the __call() magic method
I'm the __callStatic() magic method
I'm the __call() magic method
I'm the __callStatic() magic method
I'm the __callStatic() magic method
I don't understand why for (new C)->bar();
execute __callStatic()
of A
? Instance calling should made in the context of bar() method, isn't it? Is it feature of PHP?
Addition1:
Moreover, if I don't use magic methods and do explicitly call, everything works as expected:
<?php
class A {
public function foo() {
echo "I'm the foo() method of A class".PHP_EOL;
echo 'Current class of $this is '.get_class($this).PHP_EOL;
echo 'Called class is '.get_called_class().PHP_EOL;
}
}
class B {
public function bar() {
A::foo();
}
}
(new B)->bar();
Result for this:
I'm the foo() method of A class
Current class of $this is B
Called class is B
Upvotes: 3
Views: 3666
Reputation: 38416
In the bar()
method in C
, you have A::foo();
:
public function bar() {
A::foo();
}
As this method is neither creating an instance of A
, nor does C
extend A
, the ::
operator is being treated as a static-operator attempting to call a static method A::foo()
. Because foo()
isn't defined on A
, it's falling-back to the __callStatic()
method.
If you want it to call the non-static method without extending A
, you'll have to create an instance of A
:
class C {
public function bar() {
$aInstance = new A();
$aInstance->foo();
}
}
Upvotes: 3
Reputation: 62369
This is because in that case we have no instance of A
class.
Notice that
class B extends A
So new B
gives us access to nonstatic version of A->foo
.
Class C
does not extend A
so only static methods of A
are available.
Upvotes: 0