__call捕获静态方法调用
我同时使用了两种魔术方法 _ call 和 _callStatic 用于我自己的ORM/Activerow之类的实现.它们主要用于捕获某些函数调用:__call
负责getter和setter,而__callStatic
负责findBy
方法(例如findById
).
I'm using both the magic methods _call and _callStatic for my own implementation of something like an ORM/Activerow. They're mainly meant for catching certain function calls: __call
is responsible for getters and setters, and __callStatic
for findBy
methods (e.g. findById
).
要映射外键,我正在尝试将呼叫转换为getArticle
返回Article::findById()
的值.为此,我在__call
中使用这种情况:
To map foreign keys, i'm trying to convert calls to e.g. getArticle
to return the value of Article::findById()
. To do that, i'm using this case inside my __call
:
if (strstr($property, "_id")) {
return $foreignClass::findById($this->getId());
}
其中,$property
是__call
中 set 或 get 之后的子字符串,而$foreignClass
是字符串的其余部分.因此,在调用getArticle
的情况下,将获得$ property,而$foreignClass
将是Article
.
where $property
is the substring after set or get in __call
, and $foreignClass
the rest of the string. So, in the case of the call getArticle
, $property would be get and $foreignClass
would be Article
.
我放置了一些回声以确保值正确.但是,我的__call
方法而不是我的__callStatic
被调用.如果我做一个隐式静态方法findById
,它会被调用(因此它会将它识别为静态调用).如果我专门呼叫Article::findById()
,__call
也将其捕获.
I've placed some echoes to ensure that the values are correct. However, my __call
method gets called instead of my __callStatic
. If i make an implicit static method findById
, it does get called (so it does recognize it as a static call). If i specifically call Article::findById()
, __call
also catches it.
相对较新的__callStatic
是一个错误,还是我做错了什么?
Is this an error with the relatively new __callStatic
, or am i doing something wrong?
问题似乎出在这部分:
The problem seems to reside in this part:
在对象上下文中调用不可访问的方法时,会触发_call().
在静态上下文中调用不可访问的方法时,会触发__callStatic().
_call() is triggered when invoking inaccessible methods in an object context.
__callStatic() is triggered when invoking inaccessible methods in a static context.
尽管我在类上调用它,但是我从对象上下文调用它.在这种情况下,有没有办法进入静态上下文?
Though i am calling it on a class, i am calling it from an object context. Is there a way to get into the static context in this case?
由于您提供的代码是在Activity
对象的上下文中运行的,并且由于$foreignClas
的值是Article
,因此是Article
的祖先Activity
,PHP假定您打算调用祖先的实现该方法.
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);
}
);