Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use is_callable with __call?

I use PHP 5.3, which introduces closures. Because I now have closures available throughout my app (and framework), I use is_callable to see what kind of handler $callback is.

If $callback is_callable, I know enough and use that function/method/closure. If it's not callable and it's a string, it's probably the name of a method in $this class. It might exist and it might not. If I let it up to PHP, it will 'throw' a nice fatal error (I like those).

But I want to use mix-ins which means I need the magic method __call. __call is very cool, because it (can) contain(s) logic before the actual function call. BUT... what happens if after __call the called method doesn't exist? I can throw an exception, sure, but we won't know until after.

The problem is now the usefulness of is_callable, because after implementing __call, everything will return true, because everything has a fallback (being __call).

Is there a way to have both: dynamic methods and useful is_callable?

What I'd love to see is some sort of cachable magic method __is_callable that PHP will 'consult' when is_callable(array($object, $method)) is called.

On php.net, I can't find anyone who is as bumbed about this as me. This can't be it! If you use __call, you can't use is_callable anymore!?

Am I making any sense?

PS. I've looked into method_exists but that's just not good enough (even if I can filter out all closures and global functions) because it will return true for private and protected methods as well as public.

edit
I made a 'better' is_callable that checks for mix-ins but I think it's pretty expensive.

like image 900
Rudie Avatar asked May 09 '11 16:05

Rudie


1 Answers

First idea: how about checking if method exists in get_class_methods()? This function takes care of scope issues.

Second idea: if function you're looking for doesn't exist in a class, you could also check (using method_exists) if class contains __call magic method, if it doesn't than obviously call to a non-existing function is illegal. If class contains __call method, it's likely that caller knows what he's doing.

These are just my thoughts, I assume Python to be better in this kind of things.

like image 72
Dr McKay Avatar answered Oct 16 '22 00:10

Dr McKay