PHP __call vs method_exists

前端 未结 5 1006
花落未央
花落未央 2020-12-18 21:55

The Project I\'m working on contains something like a wrapper for call_user_func(_array) which does some checks before execution. One of those checks is method_exists (In Ca

相关标签:
5条回答
  • 2020-12-18 21:59

    I'd be tempted to maybe use method_exists in your __call function and throw an Exception should this fail and wrap everything in a try catch block instead of using the is_callable function.

    0 讨论(0)
  • 2020-12-18 22:04

    __call handles calls to methods that don't exist. method_exists is an introspection method that checks the existence of a method.

    How can __call be determined to handle a method? I think you have to throw an exception manually in __call if doesn't handle your request and catch the exception in the code that would otherwise use method_exists. BadMethodCallException exists for this purpose.

    0 讨论(0)
  • 2020-12-18 22:16

    method_exists tries two things:

    • Searches for the method name in the class's function table. Those are the function foo() {} type methods.
    • Checks if the class (the C code) has a (C code) get_method() function and if it has invoke it to let the class implementation decide.

    You'd need the latter. But this get_method()is not "extended" to the php script code, i.e. there is no way to let get_method() call some user defined php script code (And what would this php code return?).

    So the answer to my best knowledge is: No, it's not possible (yet?).

    The implementation of ZEND_FUNCTION(method_exists) can be found in zend/zend_builtin_functions.c and is I think fairly readable even if you don't know C but PHP.

    0 讨论(0)
  • 2020-12-18 22:17

    If you are really sure that _call always has a fall-back, you can do:

    if (method_exists($this, $method_name) || method_exists($this, '__call')) {
      // Call of the method
    }
    
    0 讨论(0)
  • 2020-12-18 22:26

    Have a look at is_callable().

    But no, if the __call() method only handles some names, then you would need some other way of checking if the call will succeed.

    Might I suggest a interface with the method canCall($function), or something? Then check if the class implements the interface. If it doesn't, just use is_callable().

    0 讨论(0)
提交回复
热议问题