我有一些类有这个签名(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
的方法ident
在b
的实例中被静态调用。这将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::方法或父::方法)