我同时使用魔术方法_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,$foreignClass
为Article
。
我已经放置了一些回声以确保值正确。但是,我的__call
方法被调用而不是我的__callStatic
。如果我创建一个隐式静态方法findById
,它会被调用(因此它会将其识别为静态调用)。如果我专门致电Article::findById()
,__call
也会抓住它。
这是一个相对较新的__callStatic
的错误,还是我做错了什么?
编辑: 这个问题似乎存在于这一部分:
在对象上下文中调用不可访问的方法时会触发_call() 在静态上下文中调用不可访问的方法时会触发__callStatic()。
虽然我在一个类上调用它,但我从一个对象上下文中调用它。在这种情况下,有没有办法进入静态上下文?
答案 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
的输出是什么?