__callStatic does not call if non-static function exists
my code:
<?php
class A {
public function CallA()
{
echo "callA" . PHP_EOL;
}
public static function CallB()
{
echo "callB" . PHP_EOL;
}
public static function __callStatic($method, $args)
{
echo "callStatic {$method}";
}
}
A::CallA();
but it will echo:
Strict Standards: Non-static method A::CallA() should not be called statically in /vagrant/hades_install/public/test.php on line 21
callA
those. CallA
does not run into a function__callStatic
how can i do this if i want to be __callStatic
called withA::CallA()
source to share
The documentation explains:
__callStatic()
fired when unavailable methods are called in a static context.
The method CallA()
in your code is available , so PHP doesn't use it __callStatic()
, and calling CallA()
is the only option.
You can force the call __callStatic()
by making it CallA()
unavailable (rename it or change its visibility to protected
or private
) or by calling it directly (ugly workaround):
A::__callStatic('CallA', array());
If you choose to protect CallA()
, you need to implement the method __call()
to call again CallA()
:
class A {
protected function CallA()
{
echo "callA" . PHP_EOL;
}
public static function CallB()
{
echo "callB" . PHP_EOL;
}
public static function __callStatic($method, $args)
{
echo "callStatic {$method}" . PHP_EOL;
}
public function __call($method, $args)
{
if ($method == 'CallA') {
$this->CallA();
}
}
}
A::CallA();
A::__callStatic('CallA', array());
$x = new A();
$x->CallA();
It outputs:
callStatic CallA
callStatic CallA
callA
source to share
Another approach is to keep the non-static method intact and prefix it statically by resolving the method name to __callStatic
.
class A {
public function CallA()
{
echo "callA" . PHP_EOL;
}
public static function __callStatic($method, $args)
{
$method_name = ltrim($method, '_');
echo "callStatic {$method_name}" . PHP_EOL;
$instance = new A();
return instance->$method_name(...$args); //this only works in PHP 5.6+, for earlier versions use call_user_func_array
}
}
A::_CallA();
This will output:
callStatic callA
callA
source to share