Magic Call Methods & Static Context in PHP
PHP's dynamic nature makes it an extremely flexible language. It can also mean confusion if you don't understand the inner workings and/or logic behind the "magic".
Today, I learned an intriguing thing about the magic methods __call()
& __callStatic()
and class inheritance. Consider the following example:
class Base
{
public function __call($name, $arguments)
{
var_dump(__METHOD__, $this, $name, $arguments);
}
public static function __callStatic($name, $arguments)
{
var_dump(__METHOD__, $name, $arguments);
}
}
class Child extends Base
{
public function doSomething()
{
Base::unknownStaticMethod();
}
}
$child = new Child();
$child->doSomething();
Here, we're making a static method call to Base
from within the Child
class. Base
doesn't have the method, so you'd expect __callStatic()
to be called, right? Nope.
string(12) "Base::__call" object(Child)#2 (0) { } string(19) "unknownStaticMethod" array(0) { }
For some reason, __call()
is hit with the current class context of our $child
object. Why?
When PHP analyzes this code, it makes an important association: Base
is the parent of the current object class Child
. So, when it sees the call to Base::unknownStaticMethod()
, it is interpreted and processed as parent::unknownStaticMethod()
.
More on parent
from php.net:
Three special keywordsself
,parent
andstatic
are used to access properties or methods from inside the class definition.
"Inside the class definition" is a very important distinction. Referencing back to the magic methods documentation:
__call()
is triggered when invoking inaccessible methods in an object context.
__callStatic()
is triggered when invoking inaccessible methods in a static context.
"Class definition" and "object context" are referring to the same context of an instantiated class.
Unless you're doing some really fancy things with inheritance and magic methods, this probably won't affect your average project. It is helpful to understand how PHP handles object context, especially related to inheritance. Late static bindingis also very on-topic, so read more about it if you're interested in this topic.
Cheers to Sheng Slogar for asking about this topic.