douhengdao4499 2014-04-30 06:51
浏览 278
已采纳

Composer使用命名空间覆盖/扩展类

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.

  • 写回答

1条回答 默认 最新

  • dongyakui8675 2014-05-27 13:48
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 任务A:大数据平台搭建(容器环境)怎么做呢?
  • ¥15 r语言神经网络自变量重要性分析
  • ¥15 基于双目测规则物体尺寸
  • ¥15 wegame打不开英雄联盟
  • ¥15 公司的电脑,win10系统自带远程协助,访问家里个人电脑,提示出现内部错误,各种常规的设置都已经尝试,感觉公司对此功能进行了限制(我们是集团公司)
  • ¥15 救!ENVI5.6深度学习初始化模型报错怎么办?
  • ¥30 eclipse开启服务后,网页无法打开
  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计