PHP __call VS method_exists(PHP __call vs method_e

2019-07-20 10:55发布

我工作的项目中包含的东西像call_user_func(_array)的包装执行之前,做一些检查。 其中一个检查是method_exists(如果所提供的第一个参数是一个类的实例和所述第二个是方法名)的另一is_callable。 如果这些检查中的一个失败的功能会抛出异常。

我的代码包含函数名(setFoo,setBar等)和PHP魔术函数重载(__call),其中处理设置,更换和某些变量(更好某些数组元素)删除阵列。

问题:如果没有定义的函数method_exists将返回false。

我是否有任何机会,如果__call函数执行请求的妥善处理,以获得正确的?

Answer 1:

__call处理,以不存在的方法的调用。 method_exists是检查的方法的存在的方法内省。

如何__call确定处理方法? 我认为你必须手动抛出一个异常,在__call如果不处理你的请求,并赶上,否则将使用代码异常method_existsBadMethodCallException存在用于此目的。



Answer 2:

看看is_callable()

不过没有关系,如果__call()方法只能处理一些名字,那么你就需要检查是否调用会成功的一些其他的方式。

我可能会建议与方法的接口canCall($function) ,还是什么? 然后检查类实现的接口。 如果没有,只是使用is_callable()



Answer 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。



Answer 4:

我会被诱惑也许使用method_exists__call功能和throw一个Exception如果失败,敷在一切try catch块,而不是使用的is_callable功能。



Answer 5:

如果你真的确信_call总是有一个回退,你可以这样做:

if (method_exists($this, $method_name) || method_exists($this, '__call')) {
  // Call of the method
}


文章来源: PHP __call vs method_exists