__如果存在非静态函数,则callStatic不调用


__callStatic does not call if there exist a non-static function

我的代码是这样的:

<?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();

但它会回应:

Strict Standards: Non-static method A::CallA() should not be called statically in /vagrant/hades_install/public/test.php on line 21
callA

也就是说,CallA不运行到函数__callStatic

如果我想使用A::CallA() 调用__callStatic,该怎么办

如文档所述:

在静态上下文中调用不可访问的方法时触发__callStatic()

代码中的方法CallA()可访问的,这就是为什么PHP不使用__callStatic(),直接调用CallA()是它唯一的选择。

您可以通过使CallA()不可访问(重命名它或将其可见性更改为protectedprivate)或直接调用它(丑陋的解决方法)来强制调用__callStatic()

A::__callStatic('CallA', array());

如果您选择使CallA()受到保护,则需要实现方法__call()才能再次调用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();

它输出:

callStatic CallA
callStatic CallA
callA

另一种方法是保持非静态方法的完整性,并在静态调用时使用前缀,解析__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();

这将输出:

callStatic callA
callA