PHP ReflectionClass hasMethod 和 __call()
我正在创建一个响应魔术 __call()
方法的动态类。问题是,由于我是在现有框架(Kohana)之上构建它的,所以它使用 ReflectionClass::hasMethod
检查该类的方法是否存在,并且似乎不存在触发 __call() 魔术方法来检查它是否存在。在这种情况下我能做什么呢?似乎如果您动态添加该方法(例如 $this->{$name} = function(){}
),它仍然无法“看到”它
I'm creating a dynamic class that responds to magic __call()
method. The problem is, since I'm building this on top of a already existing framework (Kohana), it checks if the method of the class exists using ReflectionClass::hasMethod
, and it doesn't seem to trigger the __call()
magic method for checking for it's existance. What could I do in this case? Seems like if you add the method dynamically (like $this->{$name} = function(){}
) it still can't "see" it
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有更多详细信息,我不确定这是否足够,但是您可以创建代理类来执行中间功能:
通过调用
$proxy->setMethod('foo', function () { });
,您可以动态地将方法“附加”到对象。当您调用$proxy->foo()
时,它首先会查找动态附加的方法;如果它找到一个,它就会调用它。否则,它只会委托给内部对象。现在,这种方法的问题是附加方法未绑定到代理。换句话说,
$this
不存在于附加方法的范围内。不过,这个问题可以通过 PHP 5.4+ 的功能来解决。
我们改进了
setMethod
来重新绑定传递的闭包到代理。现在,在附加方法的范围内,$this
将指向代理对象。我们可以将其重新绑定到封闭的对象,但是附加方法无法与代理(或其他附加方法)通信。为了完整起见,您需要添加
__get
和__set
魔法,以将属性访问/变异调用转发到内部对象(或在代理中处理它们,不管怎样)此外,内部对象对代理一无所知,因此它的方法(来自类定义)无论如何也不会知道任何这种动态魔法。
Without more details, I'm unsure if this would suffice, however you could create proxy class to perform intermediate functionality:
By calling
$proxy->setMethod('foo', function () { });
, you can dynamically "attach" methods to the object. When you call$proxy->foo()
, it'll first do a look-up against the dynamically attached methods; if it finds one, it'll call it. Otherwise, it'll just delegate to the internal object.Now, the problem with this approach is that attached methods aren't bound to the proxy. In other words,
$this
doesn't exist in the scope of an attached method.This can be fixed though, with features from PHP 5.4+.
We've refined
setMethod
to rebind the passed closure to the proxy. Now, in the scope of an attached method,$this
will point to the proxy object.We could have rebound it to the enclosed object, but then the attached methods couldn't talk to the proxy (or other attached methods). For completeness, you'll want to add
__get
and__set
magic, to forward property access/mutate calls to the internal object (or handle them in the proxy, whatever)Besides, the internal object has no clue about the proxy, so it's methods (from the class definition) won't know about any of this dynamic magic anyway.
正确的,因为您正在创建一个新属性,而不是方法。在撰写本文时,PHP 不支持在不经过
__call
的情况下调用属性中的匿名函数,这对反射不友好。带有匿名函数作为方法的属性在 PHP 5.4 中可以正常工作。以反射将采用的方式向类添加方法的唯一其他方法是使用 高度实验性的“runkit”扩展。
Right, as you're creating a new property, not a method. At time of writing, PHP did not support calling anonymous functions in properties without going through
__call
, which isn't Reflection-friendly. Properties-with-anonymous-functions-as-methods work properly in PHP 5.4.The only other way to add a method to a class in a way that Reflection will pick up on is using the highly experimental "runkit" extension.