如何对未知的静态方法强制__callStatic,即使存在同名的实例方法


how to force __callStatic for unknown static methods even if instance method with the same name exists?

我有一些类有这个签名(PHP 5.3):

class a {
    public static function __callStatic($name) {
        echo "unknown static method $name called";
    }
    public function foo() {
        echo "instance method foo called";
    }
}

它这样做:

a::not_known();
// unknown static method not_known called -- CORRECT
$obj = new a();
$obj->foo();
// instance method foo called -- CORRECT
a::foo();
// instance method foo called -- WRONG
// should be: unknown static method foo called

有没有什么方法可以阻止对实例方法的调用,但对未知的静态方法使用__callStatic?如果我调用静态方法,我希望运行一个静态方法。。。


编辑:为什么SergeS的以下答案不起作用(php 5.3.2):

class a {
    public $name = "a";
    function ident() {
        if( !is_object( $this )) { 
            echo "I am STATIC class a'n";
        } else {
            echo "I am INSTANCE class a'n";
            echo "'$this has name: $this->name'n";
        }
    }
}
class b {
    public $name = "b";
    function test() {
        a::ident();
    }
}
a::ident();
$a = new a();
$a->ident();
$b = new b();
$b->test();

给出以下输出:

a::ident();  --> I am STATIC class a // correct
$a->ident(); --> I am INSTANCE class a // correct
                 $this has name: a // correct
$b->test();  --> I am INSTANCE class a // wrong! should be 'STATIC class a'
                 $this has name: b // wrong! $this is an instance of 'b'!

在最后一次调用中,类a的方法identb的实例中被静态调用。这将b的实例作为$this传递给a的方法,这显然是大错特错的!

它是在定义__callStatic的过程中-如果无法访问此名称的方法,就会调用它-但a::foo是(无论它是静态的还是非静态的)-所以,如果你想保留这个构造,请将它放在foo方法的开头:

if( is_object( $this )) if( $this instanceof a ) { 
    // Do non-static
    return;
} 
// Do static here

PS编辑示例以确保它也将是相同的实例-但这并不总是正确的选择静态或非静态调用的答案,因为如果我有这个层次结构

A类->B类->C类(C类同时实现A和B),如果我想从A调用特定的方法,我将编写A::方法(类似于B中的特定方法,通过调用B::方法或父::方法)