4

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

为了映射外键,我试图将调用转换为例如getArticle返回Article::findById(). 为此,我在我的内部使用了这个案例__call

if (strstr($property, "_id")) {  
 return $foreignClass::findById($this->getId()); 
}

在哪里$propertysetget in之后的子字符串__call,以及$foreignClass字符串的其余部分。因此,在 call 的情况下getArticle,$property 将是 get 并且$foreignClass将是Article

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

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

编辑:问题似乎出在这部分:

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

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

4

2 回答 2

3

Since the code you give runs in the context of an Activity object and since the value of $foreignClas is Article, which is an ancestor of Activity, PHP assumes that you are intending to call an ancestor's implementation of the method.

To break out of the object context there is AFAIK no option other than this absolutely hideous technique:

$id = $this->getById();
return call_user_func(
    function() use($foreignClass, $id) { 
        return call_user_func("$foreignClass::findById", $id);
    }
);
于 2012-11-05T15:40:13.327 回答
0

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

于 2012-11-05T13:17:15.520 回答