__call捕获静态方法调用

时间:2012-11-05 12:47:50

标签: php activerecord orm getter-setter

我同时使用魔术方法_call _callStatic来实现我自己的ORM / Activerow之类的实现。它们主要用于捕获某些函数调用:__call负责getter和setter,__callStatic负责findBy方法(例如findById)。

要映射外键,我试图将呼叫转换为例如getArticle返回Article::findById()的值。为此,我在__call

中使用了这个案例
if (strstr($property, "_id")) {  
 return $foreignClass::findById($this->getId()); 
}

其中$property set get __call之后的子字符串,$foreignClass是字符串的其余部分。因此,如果是getArticle来电,则$ property为get,$foreignClassArticle

我已经放置了一些回声以确保值正确。但是,我的__call方法被调用而不是我的__callStatic。如果我创建一个隐式静态方法findById,它会被调用(因此它会将其识别为静态调用)。如果我专门致电Article::findById()__call也会抓住它。

这是一个相对较新的__callStatic的错误,还是我做错了什么?

编辑: 这个问题似乎存在于这一部分:

  在对象上下文中调用不可访问的方法时会触发

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

虽然我在一个类上调用它,但我从一个对象上下文中调用它。在这种情况下,有没有办法进入静态上下文?

2 个答案:

答案 0 :(得分:2)

由于您提供的代码在Activity对象的上下文中运行,并且由于$foreignClas的值为Article,这是Activity的祖先,因此PHP假定您打算使用该方法的to call an ancestor's implementation

要打破对象上下文,除了这种绝对可怕的技术外,AFAIK没有其他选项:

$id = $this->getById();
return call_user_func(
    function() use($foreignClass, $id) { 
        return call_user_func("$foreignClass::findById", $id);
    }
);

答案 1 :(得分:0)

__callStatic魔术方法仅在PHP 5.3中引入。在此之前,我认为静态调用通过__call路由,就像正常的方法调用一样。我的猜测是你使用的是PHP版本< 5.3。命令行上php -v的输出是什么?