2016-09-28 71 views
1

我正在开发一个自定义的ORM,这里是一个简单的例子来演示这个问题:PHP:__call调用,而不是__callStatic

class Foo { 
    public static function __callStatic($name, $args){ 
     if($name == "getBar"){ 
      return "Bar"; 
     } 
     return NULL; 
    } 

    public function __call($name, $args){ 
     if($name == "getFoo"){ 
      $model = "Foo"; 
      $method = "getBar";    
      return $model::$method();    
     } 
     return NULL; 
    } 
} 

class Foo2 { 
    public function __call($name, $args){ 
     if($name == "getFoo"){ 
      $model = "Foo"; 
      $method = "getBar";    
      return $model::$method();    
     } 
     return NULL; 
    } 
} 

echo Foo::getBar();//Bar 

$foo = new Foo; 
var_dump($foo->getFoo()); //Null though I'm expecting Bar 

$foo = new Foo2; 
var_dump($foo->getFoo()); //Bar 

那么,为什么同样的方法中富调用时触发__call和内部Foo2触发__callStatic

+0

有趣的事情。很显然'__callStatic'只能从其他类中运行,而不能从其他类运行?很高兴知道! – Xatenev

+0

看起来更像是你不能从'__call'调用'__callStatic'。或者,PHP可能会因堆栈超载而失败,或者由于某种原因禁用了此功能。 – tilz0R

+0

@ tilz0R第3种方法从__call调用。 – Xatenev

回答

1

那是因为在第一次调用中你得到了返回的Null,你在一个对象上下文中。所以它调用__call()而不是__callStatic()。在第一种情况下,Foo :: getBar()在类Foo的实例范围内调用,所以Foo :: getBar()实际上与(实例) - > getBar()相同。 )这当然不是一个静态的调用。

EDIT2:刚刚发现关于你的问题一个问题的答案+:Why does PHP prefer __call() to __callStatic()?

+0

在'Foo2'示例中,它们也处于对象上下文中,但它的行为不同...... – deceze

+0

@deceze请参阅编辑。我试着再解释一下。 – Xatenev

+0

很高兴看到关于它的一些文档。奇怪的PHP检查是否在同一类的实例中调用静态方法(我认为它应该不重要 – user1270172