views:

548

answers:

4

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?

+1  A: 

method_exists tries to things:

  • Searching for the method name in the classes function table. Those are the function foo() {} type methods.
  • Checking 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.

VolkerK
+2  A: 

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().

gnud
+2  A: 

Oh no,

  • __call is here to handle calls to methods that doesn't exist ;
  • method_exists is an introspection method who checks the existence of a method.

How to know if __call handles a method ?

I think you have to throw an exception manualy if __call doesn't handle your request and create a method who checks if __call throw this exception.

Is it clear (i don't speack english really well) ?

JF Simon
It seems `__call` has no notion of "failing", so it looks like throwing an `NotImplementedException` (or similar) in the __call method would be the way to do this.
Alex Barrett
A: 

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.

Nev Stokes