'PHP __call vs method_exists
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 Case the supplied first argument is an instance of a class and the second is a method name) The other is_callable. The function will throw an exception if one of those checks fails.
My Code contains an array with function names (setFoo, setBar, etc.) and the php magic function for overloading (__call) which handles setting, replacing and deletion of certain variables (better certain array elements).
The Problem: method_exists will return false if the function is not defined.
Do I have any chance to get a true if the __call function does proper handling of the request?
Solution 1:[1]
__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.
Solution 2:[2]
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().
Solution 3:[3]
method_exists tries two things:
- Searches for the method name in the class's function table.
Those are thefunction 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.
Solution 4:[4]
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
}
Solution 5:[5]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | outis |
| Solution 2 | gnud |
| Solution 3 | greybeard |
| Solution 4 | milkovsky |
| Solution 5 | Nev Stokes |
