PHP __call 与 method_exists
Posted
技术标签:
【中文标题】PHP __call 与 method_exists【英文标题】:PHP __call vs method_exists 【发布时间】:2010-12-03 02:30:57 【问题描述】:我正在处理的项目包含类似于 call_user_func(_array) 的包装器,它在执行前会进行一些检查。 其中一项检查是 method_exists (如果提供的第一个参数是类的实例,第二个是方法名称) 另一个是_callable。 如果其中一项检查失败,该函数将引发异常。
我的代码包含一个带有函数名称(setFoo、setBar 等)的数组和用于重载的 php 魔术函数(__call),它处理某些变量的设置、替换和删除(更好的某些数组元素)。
问题: 如果未定义函数,method_exists 将返回 false。
如果 __call 函数正确处理请求,我是否有机会获得 true?
【问题讨论】:
好问题,我会玩这个。 需要的是另一种“神奇的方法” __canCall 什么的…… is_callable() 适用于类的实例。我根本不明白您为什么要使用 method_exists() 。 is_callable() 做了所有 method_exists() 做的事情,而且它与 __call() 一起工作。 【参考方案1】:__call
处理对不存在的方法的调用。 method_exists
是一种检查方法是否存在的自省方法。
__call
如何确定处理方法?我认为您必须在 __call
中手动抛出异常,如果不处理您的请求并在代码中捕获异常,否则将使用 method_exists
。 BadMethodCallException
就是为此目的而存在的。
【讨论】:
似乎__call
没有“失败”的概念,所以看起来像在 __call 方法中抛出一个 NotImplementedException
(或类似的)将是这样做的方法。【参考方案2】:
看看is_callable()
。
但是不,如果__call()
方法只处理一些名称,那么您将需要其他方法来检查调用是否成功。
我可以建议使用canCall($function)
方法的接口,还是什么?然后检查该类是否实现了该接口。如果没有,请使用is_callable()
。
【讨论】:
is_callable() 如果定义了 __call() 会自动返回 true,使得 is_callable() 不可靠(因为它不能确保 __call() 满足请求)【参考方案3】:method_exists 尝试了两件事:
在类的函数表中搜索方法名称。 这些是function foo()
类型的方法。
检查类(C 代码)是否有(C 代码)get_method()
函数,以及是否调用它让类实现决定。
你需要后者。但是这个get_method()
没有“扩展”到 PHP 脚本代码,也就是说,没有办法让 get_method() 调用一些用户定义的 PHP 脚本代码(这个 PHP 代码会返回什么?)。
因此,据我所知,答案是:不,这是不可能的(还没有?)。
ZEND_FUNCTION(method_exists)
的实现可以在zend/zend_builtin_functions.c
中找到,我认为即使你不懂 C 而懂 PHP,也相当易读。
【讨论】:
【参考方案4】:如果你真的确定 _call 总是有一个后备,你可以这样做:
if (method_exists($this, $method_name) || method_exists($this, '__call'))
// Call of the method
【讨论】:
【参考方案5】:我很想在你的 __call
函数中使用 method_exists
和 throw
和 Exception
如果这失败并将所有内容包装在 try
catch
块中,而不是使用 is_callable
功能。
【讨论】:
以上是关于PHP __call 与 method_exists的主要内容,如果未能解决你的问题,请参考以下文章
php中method_exists()和is_callable()如何进行语句判断