Question

I have one namespace (for example \App\) that contains all my app encapsulated, currently I'm using composer to autoload this namespace using PSR-0 and checking for two different folders, "Main" and "Client". (Giving priority to the client folder, allowing me to override the main app functionality to meet the client's requests by only creating the necessary override files in the client's folder)

Now, I'm thinking that it would be better if the client's override classes extended the original one, because I realized that the main use for this is to edit only some of the class methods, and I want to future proof the "override class" for new methods that could appear in the "main class". And I've been struggling with a way to make this happen, keeping the namespaces.

Example: Sales Controller Class ==> \App\Controller\Sale

  • If there isn't a "Client/App/Controller/Sale.php" file it uses the default "Main/App/Controller/Sale.php"
  • But if there is, what I want is that "Client/App/Controller/Sale.php" could be able to extend "Main/App/Controller/Sale.php"

    <?php 
      namespace App\Controller
      use \Main\Controller\Sale as OriginalClass //The Sale class in Main Folder
    
      class Sale extend OriginalClass {...}
    
  • This way, I could override only some methods in the client's class and if the main class gets updated it would be reflected in the client's app.

The problem is, that since both, the client and main class are in the \App\ namespace, I can't figure out a way to get the "use" statement above to work. The main reason is that any prepended namespace (in the example "\Main + namespace) that I put in it won’t work, because the file's namespace would be different.

Another way I thought it could work is by tinkering with the composer autoload, and check if the namespace starts with "Main" or maybe "Original", then remove that part from the namespace and force to use the "Main" folder. But I couldn't find where this could be implemented.

Another solution I considered was to subdivide the main class functionality in sub classes, that could be overridden using the current autoload scheme, but I don't know if it is wise to have so many classes and files scattered through the system.

Any help or guidance is always welcome.

Was it helpful?

Solution

No Solution, but a workaround

I ended up separating the clients and main classes namespaces. Then, I made a function that recives a class name and checks if the class exists in the client's folder and prepend the "Client\" namespace, or append the "Main\" namespace before initializing.

So

$class = "Path\\To\\My\\Class";
$class = checkClass($class);
// Now class is either "Client\\Path\\To\\My\\Class; or Main\\Path\\To\\My\\Class;

//Uses:
$object = new $class();
$static = $class::StaticMethod();

Also, the "Client" version of the classes extends their "Main" --base-- class.

Eg: Client\MyClass extends Main\MyClass

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top