Working with a PHP library class, and I'd like to wrap all of its public functions in a subclass... Something along the lines of:
class BaseClass
{
function do_something()
{
some;
stuff;
}
function do_something_else()
{
other;
stuff;
}
/*
* 20-or-so other functions here!
*/
}
class SubClass extends BaseClass
{
function magicalOverrideEveryone()
{
stuff-to-do-before; // i.e. Display header
call_original_function(); // i.e. Display otherwise-undecorated content
stuff-to-do-after; // i.e. Display footer
}
}
Boiling it down, I'd prefer not to have to override every superclass method with the same wrapper code, if there's a [somewhat elegant / clean] way to do it all in one place.
Is this possible? I suspect I'm in metaprogramming land here, and don't even know if PHP offers such a beast, but figured I'd ask...
you might be looking for the decorator pattern:
since this is not what you want, maybe this link is of help? http://code.google.com/p/php-aop/
If I understand you right, you want to extend a class, but not allow any of methods from the parent to be called. Instead, you want to call all of the methods yourself in one method in the new class.
So why do you even want to inherit in the first place? It sounds a lot like you should just create an adapter/decorator for your BaseClass.
You could do this easily with the
__call
magic method and a generic "proxy" class which doesn't inherit directly from the base class.Here is a (near) complete implementation of a proxying class which wraps whatever object you pass it. It will invoke some "before" and "after" code around each method call.
You would of course want to add a bit of error handling, like asking the proxied object if it responds to the given method in
__call
and raising an error if it doesn't. You could even design the Proxy class to be a base-class for other proxies. The child proxy classes could implementbefore
andafter
methods.The downside is that your "child class" no longer implements
BaseClass
, meaning if you're using type-hinting and want to demand that only objects of typeBaseClass
are passed into a function, this approach will fail.If the method names of SubClass may differ slightly from the original method names of BaseClass, you could write a generic wrapper with
__call()
. If the method names must match, I don't see how you could achieve your goal without manually overwriting each method. Maybe you could use the funcall PECL to do this - but you'd have to be able to load that PECL in the first place.If you can make the methods of BaseClass
protected
, the__call()
approach in SubClass will work.If you do not need to extend the class, @meager's approach is perfectly fine. Please note that __call() and call_user_func_array() do impose a certain overhead.