Php Symfony 5.1服务注册取决于数据库数据

Php Symfony 5.1服务注册取决于数据库数据,php,symfony,dependency-injection,doctrine-orm,symfony5,Php,Symfony,Dependency Injection,Doctrine Orm,Symfony5,我正在使用Symfony 5.1,希望为我的应用程序构建一个插件系统。 核心应用程序的代码放在src/目录中,插件将存储在custom/目录中 插件的结构是预定义的,如下所示: custom |--SomePlugin |--Controller |--Subscriber |--... |--SomePlugin.php 还有一个数据库,其中包含插件状态的表,无论插件是否处于活动状态 | name | version | status | | ------ | -----

我正在使用Symfony 5.1,希望为我的应用程序构建一个插件系统。 核心应用程序的代码放在
src/
目录中,插件将存储在
custom/
目录中

插件的结构是预定义的,如下所示:

custom
|--SomePlugin
  |--Controller
  |--Subscriber
  |--...
  |--SomePlugin.php
还有一个数据库,其中包含插件状态的表,无论插件是否处于活动状态

| name   | version | status |
| ------ | ------- | ------ |
| string | string  | bool   |
如何从插件名称空间加载服务 我的应用程序已被设置为从默认的
App
命名空间加载服务-同时自动加载控制器。由于这些服务和控制器的加载取决于从数据库接收到的状态,因此我使用了以下内核定制

// src/Kernel.php

namespace App;

class Kernel extends BaseKernel
{
    use MicroKernelTrait;

    // ...

    protected function configureRoutes(RoutingConfigurator $routes): void
    {
        $activePlugins = $this->getActivePlugins();

        $customDirectories = scandir($this->getProjectDir() . '/custom/');

        foreach ($customDirectories as $customDirectory) {
            if (!in_array($customDirectory, ['.', '..']) &&
                is_dir($this->getProjectDir() . '/custom/' . $customDirectory . '/Controller/')) {

                $prefix = call_user_func([$customDirectory . '\\' . $customDirectory, 'name']);
                $prefix = preg_replace('/[^a-z0-9]/i', '-', $prefix);
                $prefix = strtolower($prefix);

                if(in_array($prefix, $activePlugins)) {
                    $routes->import('../custom/' . $customDirectory . '/Controller/', 'annotation')
                        ->namePrefix($prefix . '_');
                }
            }
        }
    }

    // ...
}
函数的作用是:返回一个包含所有活动插件的数组。如果插件处于活动状态,则路由应为寄存器这很好用。

但是。。。要配置服务,我必须使用
configureContainer()
函数

// src/Kernel.php

// ...

protected function configureContainer(ContainerConfigurator $container): void
{
   $activePlugins = $this->getActivePlugins();

   // ...
}

// ...
问题是:此时内核没有启动,因此
getActivePlugins()
函数无法访问容器,我无法使用Doctrine从数据库获取数据


是否有方法在启动内核后注册服务?

否。在启动内核后不能添加服务。事实上,您需要知道服务和路由被“编译”到缓存目录中。如果您想在数据库中启用插件并自动提供其服务,那么您将感到失望。每次插件更改后,您都需要一些东西来清除和重建缓存。如果您能够满足这个要求,那么您需要为configureContainer设置自己的数据库连接以供使用。那么第二次编译内核呢?首先注册“核心”服务,然后注册插件服务?怎么样?您仍然无法将服务添加到已编译的容器中。您需要清除缓存以修改容器。欢迎使用某种容器生成器,在编译过程中收集所有激活的插件。这也是许多内容管理系统(CMS)必须解决的问题。你可以看看其他基于Symfony的CMS,看看它们是如何解决的,但Cerad是对的,每次更改后你都会清除并重建缓存。还要注意的是,像OPCache和其他二级缓存会在这个过程中造成困难。否。内核启动后,无法添加服务。事实上,您需要知道服务和路由被“编译”到缓存目录中。如果您想在数据库中启用插件并自动提供其服务,那么您将感到失望。每次插件更改后,您都需要一些东西来清除和重建缓存。如果您能够满足这个要求,那么您需要为configureContainer设置自己的数据库连接以供使用。那么第二次编译内核呢?首先注册“核心”服务,然后注册插件服务?怎么样?您仍然无法将服务添加到已编译的容器中。您需要清除缓存以修改容器。欢迎使用某种容器生成器,在编译过程中收集所有激活的插件。这也是许多内容管理系统(CMS)必须解决的问题。你可以看看其他基于Symfony的CMS,看看它们是如何解决的,但Cerad是对的,每次更改后你都会清除并重建缓存。还要注意的是,辅助缓存(如OPCache)和其他缓存会在该过程中造成困难。