__call overload detection

php.internals

Andrew Yochum

20 years ago
Currently there is no way to detect if the __call overloads a particular method. Property overloading has __isset now in 5.1 - maybe for method overloading the equivalent should be something like __iscallable. Maybe method_exists should remain as is, as the method won't ever really exist but is_callable would/could use it, or perhaps some new function. Is this a reasonable request? Thoughts? Regards, Andrew
-- Andrew Yochum Plexpod andrew@plexpod.com 718-360-0879

Andi Gutmans

20 years ago
Why not just use Reflection API to check? It seems quite trivial to do so. At 12:57 PM 1/3/2006, Andrew Yochum wrote:

Marcus Börger

20 years ago
Hello Andi, the point is probably that there is no way in determinig whether a certain function is supposed to work prior to calling it. regards marcus Wednesday, January 4, 2006, 12:45:23 AM, you wrote:
> Why not just use Reflection API to check? It seems quite trivial to do so.
> At 12:57 PM 1/3/2006, Andrew Yochum wrote: >>Currently there is no way to detect if the __call overloads a particular >>method. Property overloading has __isset now in 5.1 - maybe for method >>overloading the equivalent should be something like __iscallable. Maybe >>method_exists should remain as is, as the method won't ever really exist >>but is_callable would/could use it, or perhaps some new function. >> >>Is this a reasonable request? Thoughts? >> >>Regards, >>Andrew >>-- >>Andrew Yochum >>Plexpod >>andrew@plexpod.com >>718-360-0879 >> >>-- >>PHP Internals - PHP Runtime Development Mailing List >>To unsubscribe, visit: http://www.php.net/unsub.php
Best regards, Marcus

Andi Gutmans

20 years ago
Right but you can do it in user-land. If you're writing __call() you could add an additional method to see if it's mapped. I don't think it's quite as common as isset(). At 04:05 PM 1/3/2006, Marcus Boerger wrote:

Marcus Börger

20 years ago
Hello Andi, we didn't saw any necessaty for __isset either. marcus Wednesday, January 4, 2006, 1:41:44 AM, you wrote:

Andi Gutmans

20 years ago
I think it's different especially as it's complementary to unset() but I don't intend to get into an argument about it. In any case, the tools for Andrew to resolve this programmatically on the PHP level exist even if the syntax isn't 100% of what he'd like it to be. Over and out. Andi At 05:24 PM 1/3/2006, Marcus Boerger wrote:

Andrew Yochum

20 years ago
On Tue, Jan 03, 2006 at 05:29:11PM -0800, Andi Gutmans wrote:
> I think it's different especially as it's complementary to unset() > but I don't intend to get into an argument about it.
I see your point there about isset and unset being a matched pair. From my perspective, call is similar to unset. It is implemented as a "black box" and has no complementary introspection method like isset to figure out how the black box works - at least as part of the language. unset has side-effects by nature of its intention, as might use of call. isset is intended to be a no side-effect poke at a property, but no such complement exists for call.
> In any case, the tools for Andrew to resolve this programmatically on > the PHP level exist even if the syntax isn't 100% of what he'd like it to > be.
100% agreed and I have done so. I've brought it up for the community's benefit, as I think it is an area that has room for some improvement. I can see it becoming an issue as the frameworks and libraries for 5 continues to build and are integrated. I don't want to argue either - just trying to have productive discussion. Regards, Andrew
-- Andrew Yochum Plexpod andrew@plexpod.com 718-360-0879

Stanislav Malyshev

20 years ago
MB>> the point is probably that there is no way in determinig whether a MB>>certain function is supposed to work prior to calling it. This is the case for all functions. For example, if you call mysql_query, you have no way of knowing if it would succeed prior to calling it. So __call is not much different - you know it will call __call but you don't know if the call would succeed.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Derick Rethans

20 years ago
On Wed, 4 Jan 2006, Stanislav Malyshev wrote:
> MB>> the point is probably that there is no way in determinig whether a > MB>>certain function is supposed to work prior to calling it. > > This is the case for all functions. For example, if you call mysql_query, > you have no way of knowing if it would succeed prior to calling it. So > __call is not much different - you know it will call __call but you don't > know if the call would succeed.
That is not fully true, as you can use function_exists() on mysql_query, where there is no such possibility for methods that are overloaded with __call(). Derick

Stanislav Malyshev

20 years ago
DR>>That is not fully true, as you can use function_exists() on DR>>mysql_query, where there is no such possibility for methods that are DR>>overloaded with __call(). That's correct, of course - this is the whole point of __call - it makes _any_ function exist. Now, calling these functions may succeed or fail - just as calling any other functions may succeed or fail.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Marcus Börger

20 years ago
Hello Stanislav, but that is a way of having __call that obviously doesn't fit the real world. In a real world application i only implement a few things with call and dislike having all the others implemented automatically also. And the i have to care about error generation while the engine could help me a lot so that my error messages look and behave just like they would if there is no __call. But that would indeed require some __exists() or __implemented() support(). marcus Wednesday, January 4, 2006, 10:24:20 AM, you wrote: DR>>>That is not fully true, as you can use function_exists() on DR>>>mysql_query, where there is no such possibility for methods that are DR>>>overloaded with __call().
> That's correct, of course - this is the whole point of __call - it makes > _any_ function exist. Now, calling these functions may succeed or fail - > just as calling any other functions may succeed or fail.
> -- > Stanislav Malyshev, Zend Products Engineer > stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
Best regards, Marcus

Stanislav Malyshev

20 years ago
MB>> but that is a way of having __call that obviously doesn't fit the real MB>>world. In a real world application i only implement a few things with call MB>>and dislike having all the others implemented automatically also. And the MB>>i have to care about error generation while the engine could help me a lot MB>>so that my error messages look and behave just like they would if there MB>>is no __call. But that would indeed require some __exists() or MB>>__implemented() support(). Nothing prevents you from having __implemented or __whateveryoulike. However, I don't see how engine could know beforehand if your __call would succeed or not, so __implemented has no relation whatsoever to __call, unless you make this relation in your code - and engine can't know you did.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Lukas Smith

20 years ago
Stanislav Malyshev wrote:
> MB>> but that is a way of having __call that obviously doesn't fit the real > MB>>world. In a real world application i only implement a few things with call > MB>>and dislike having all the others implemented automatically also. And the > MB>>i have to care about error generation while the engine could help me a lot > MB>>so that my error messages look and behave just like they would if there > MB>>is no __call. But that would indeed require some __exists() or > MB>>__implemented() support(). > > Nothing prevents you from having __implemented or __whateveryoulike. > However, I don't see how engine could know beforehand if your __call would > succeed or not, so __implemented has no relation whatsoever to __call, > unless you make this relation in your code - and engine can't know you > did.
I think its obvious that you can implement things in userland or inside the engine. The main advantage of doing it inside the engine is that it then becomes the standard way of doing things, where as with userland its likely that several competing "standards" will emerge. Not because of real advantages, but just because of lack of a central standard. However maybe its sufficient to just have an interface that defines the signature of such a "check if method is implemented by __call()" method along with a bit of text. That should imho be a sufficient approach. Without the need of adding yet another magic method to the engine itself. regards, Lukas

Marcus Börger

20 years ago
Hello Lukas, that's right now also impossible. We would need an api change for that. Or we would need to have the interface support deeply in the engine like we have with the iterators. If that is ok for all among the engine developers i think i can easily add it. marcus Wednesday, January 4, 2006, 12:50:56 PM, you wrote:
> Stanislav Malyshev wrote: >> MB>> but that is a way of having __call that obviously doesn't fit the real >> MB>>world. In a real world application i only implement a few things with call >> MB>>and dislike having all the others implemented automatically also. And the >> MB>>i have to care about error generation while the engine could help me a lot >> MB>>so that my error messages look and behave just like they would if there >> MB>>is no __call. But that would indeed require some __exists() or >> MB>>__implemented() support(). >> >> Nothing prevents you from having __implemented or __whateveryoulike. >> However, I don't see how engine could know beforehand if your __call would >> succeed or not, so __implemented has no relation whatsoever to __call, >> unless you make this relation in your code - and engine can't know you >> did.
> I think its obvious that you can implement things in userland or inside > the engine. The main advantage of doing it inside the engine is that it > then becomes the standard way of doing things, where as with userland > its likely that several competing "standards" will emerge. Not because > of real advantages, but just because of lack of a central standard.
> However maybe its sufficient to just have an interface that defines the > signature of such a "check if method is implemented by __call()" method > along with a bit of text. That should imho be a sufficient approach. > Without the need of adding yet another magic method to the engine itself.
> regards, > Lukas
Best regards, Marcus

Stanislav Malyshev

20 years ago
LS>>I think its obvious that you can implement things in userland or inside the LS>>engine. The main advantage of doing it inside the engine is that it then LS>>becomes the standard way of doing things, where as with userland its likely LS>>that several competing "standards" will emerge. Not because of real LS>>advantages, but just because of lack of a central standard. I don't see anything there to be implemented in the engine. What exactly you want the engine to do? Only thing I can see is to support it in is_callable() - I'm not sure if it worth it but we can do so that is_callable would check if the object has __callable function or implements interface CallableCheck or whatever and if it has, call it. Though I'm not sure it really worth the hassle - all three people that need it in real world probably already implemented it in userland anyway.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Marcus Börger

20 years ago
Hello Stanislav, where is the relation between __isset and __get/set/unset? marcus Wednesday, January 4, 2006, 12:32:29 PM, you wrote: MB>>> but that is a way of having __call that obviously doesn't fit the real MB>>>world. In a real world application i only implement a few things with call MB>>>and dislike having all the others implemented automatically also. And the MB>>>i have to care about error generation while the engine could help me a lot MB>>>so that my error messages look and behave just like they would if there MB>>>is no __call. But that would indeed require some __exists() or MB>>>__implemented() support().
> Nothing prevents you from having __implemented or __whateveryoulike. > However, I don't see how engine could know beforehand if your __call would > succeed or not, so __implemented has no relation whatsoever to __call, > unless you make this relation in your code - and engine can't know you > did.
Best regards, Marcus

Peter Brodersen

20 years ago
On Wed, 4 Jan 2006 10:19:22 +0100 (CET), in php.internals derick@php.net (Derick Rethans) wrote:
>That is not fully true, as you can use function_exists() on mysql_query, >where there is no such possibility for methods that are overloaded with >__call().
.. with some exceptions though (function names might exist but still unusable), as mentioned in the documentation.
-- - Peter Brodersen

Sara Golemon

20 years ago
> Currently there is no way to detect if the __call overloads a particular > method. Property overloading has __isset now in 5.1 - maybe for method > overloading the equivalent should be something like __iscallable. Maybe > method_exists should remain as is, as the method won't ever really exist > but is_callable would/could use it, or perhaps some new function. >
This'll do what you want: http://libssh2.org/dist/callable-1.0.tgz It's PEAR packaged so compiling/installing should be simple enough.... Dunno if it's worth dropping into PECL though... -Sara

Andrew Yochum

20 years ago
On Wed, Jan 04, 2006 at 02:20:45PM -0800, Sara Golemon wrote:
> > Currently there is no way to detect if the __call overloads a particular > > method. Property overloading has __isset now in 5.1 - maybe for method > > overloading the equivalent should be something like __iscallable. Maybe > > method_exists should remain as is, as the method won't ever really exist > > but is_callable would/could use it, or perhaps some new function. > > > This'll do what you want: > > http://libssh2.org/dist/callable-1.0.tgz > > It's PEAR packaged so compiling/installing should be simple enough.... Dunno > if it's worth dropping into PECL though... > > -Sara
Thanks Sara. Nice to see that others have the need. Works like a charm. You rock. Marcus, is this along the lines of what you had in mind for the (possible) implementation? This doesn't use interfaces, but that seems trivial. I wasn't clear if you'd envisioned taking it one step further and do the check before invocations of __call or not. Regards, Andrew
-- Andrew Yochum Plexpod andrew@plexpod.com 718-360-0879

Sara Golemon

20 years ago
>> This'll do what you want: >> >> http://libssh2.org/dist/callable-1.0.tgz >> > Thanks Sara. Nice to see that others have the need. Works like a > charm. You rock. >
Just for clarification. I didn't have a need for this, it's just something I threw together today since it was simple...
> Marcus, is this along the lines of what you had in mind for the > (possible) implementation? This doesn't use interfaces, but that seems > trivial. I wasn't clear if you'd envisioned taking it one step further > and do the check before invocations of __call or not. >
I left interfaces out 'cause I wanted it to work easily with PHP4. As to introducing the check prior to invoking __call()... that seems like overkill. If __call() doesn't think it should be callable it should trigger_error() or throw when its invoked that way. __callable() only has meaning for avoiding the errors that calling an uncallable function would produce. -Sara