Symfony 2/3 获取实现接口的目录中的类


Symfony 2/3 Get Classes in Directory that Implement an Interface

Symfony 2或3中是否有一种很好的方法来加载实现特定接口的目录中的所有类?

从 Symfony 3.3/3.4 开始,只需使用配置即可(无需编写自定义 CompilerPass):

# config/services.yaml
services:
# ...
_instanceof:
    App'HandlerInterface:
        tags: ['app.handler']
App'HandlerCollection:
    # inject all services tagged with app.handler as first argument
    arguments: [!tagged app.handler]

如果需要将服务限制为从单个目录注册,请参阅使用资源导入

引用:

  • https://symfony.com/doc/current/service_container/3.3-di-changes.html#auto-configure-with-instanceof
  • https://symfony.com/doc/3.4/service_container/tags.html#reference-tagged-services
  • http://symfony.com/doc/3.4/service_container.html#importing-many-services-at-once-with-resource

简短的回答是:你不能。

在加载文件之前,您不知道文件中的内容。

长答案(考虑到您在问题下的评论中写的内容):

在加载文件之前,您唯一知道的是它的名称。因此,解决方案之一是使用固定模式(如UserModuleProductModule等)命名模块的类(和文件)。这样,您可以按名称加载所有模块。但这是我不建议的解决方案。

我认为您应该改变方法并反转工作流程。创建一个类,您将在其中定义需要加载的所有模块。在Symfony中,它默认称为AppKernel,在其中定义要加载和初始化的捆绑包(模块)。

这有几个优点。

  • 您可以有多个应用程序入口点,并为每个入口点配置不同的模块。

  • 您可能有几个不同的环境(如生产和开发),其中加载了不同的模块。(例如,在开发中添加一些模块,如分析器)

  • 此外,依赖关系管理要容易得多,因为您可以加载定义的模块并通过自动加载添加它们的依赖关系。

总的来说,我认为您应该避免手动加载任何 php 文件(autoload.php 或包含自动加载器的类似文件除外)。