Dynamic inheritence for application extension in PHP
In any big enough PHP application, comes a time when some of the objects that are used in the application might be overriden by some extensions, to customize the functionnality of the application.
Let's take a example: your application has a class Employee that deals with the logic for every employee in your client's organization. Now imagine you have a client that wants to buy your application but wants to synchronize the employee table with its LDAP directory - fair enough.
What we want to do, is really to extend the Employee class, so that we can change the code of a few functions and add a few others to give your final client the behaviour he asks for.
So we add an extension (a folder really) where we put a class that extends Employee. We call that class LDAP_Employee for the sake of clarity:
class LDAP_Employee extends Employee
{
function LDAP_Employee($id)
{
$this->Employee($id);
}
// Some more code to deal with the LDAP directory ...
// ...
}Now the problem we have, is that everywhere in our application, the instances are still created out of the original Employee class.
The trick is to use function variables to create the instances.
Let's say you have a global variable defined at the top of the application:
$GLOBALS['ClassDefinitions']['Employee'] = 'Employee'; // Name of the original classNow, to instanciate an employee we just need to do:
$MyEmployee = new $GLOBALS['ClassDefinitions']['Employee']($MyId);If we want to use the LDAP_Employee class, we just need to change the global once, high enough in the application initialization routine - where the extensions are loaded, basically:
$GLOBALS['ClassDefinitions']['Employee'] = 'LDAP_Employee'; // Now we'll use the overriden class everywhereThe rest of the code is left unchanged, but the behaviour of the whole application is now changed.
The only downside of this method, is that the overriden classes need to know exactly what class they extend (you can't have a variable after the extend keyword). So if you have a second extension that wanted to extends Employee, you're cooked. (you can, however, have a third extension that extends LDAP_Employee, of course)
