为 Symfony MicroKernel 注册自定义配置命名空间

register custom config namespace for Symfony MicroKernel

我有一个带有 MicroKernel 的应用程序,我想将 Symfony 的 TreeBuilder 与自定义配置一起使用,因为该应用程序非常通用,我希望尽可能多地进行外部配置。我的问题是,我无法让我的自定义 namespace 注册到 symfony:

There is no extension able to load the configuration for "research" 
(in /var/www/html/src/app/config/config.yml). Looked for 
namespace "research", found "framework", "twig", 
"sensio_framework_extra", "web_profiler"

我有这个Configurationclass:

<?php
namespace App\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode    = $treeBuilder->root('research');

        // @formatter:off
        $rootNode
            ->children()
                ->arrayNode('questions')
                    ->children()
                        ->integerNode('client_id')->end()
                        ->scalarNode('client_secret')->end()
                    ->end()
                ->end()// twitter
            ->end();
        // @formatter:on

        return $treeBuilder;
    }
}

和我的 AppExtension:

<?php
namespace App\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;

class AppExtension extends ConfigurableExtension
{
    // note that this method is called loadInternal and not load
    protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
    {
        dump($mergedConfig);
    }

    public function getAlias()
    {
        return 'research';
    }
}

在我的 AppKernel class 中,我正在像这样初始化扩展,因此 我也从我的 dump($mergedConfig) 调用中获得了输出AppExtension 来自我的原始 research.yml

<?php
namespace App;

use App\DependencyInjection\AppExtension;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;

$loader = require __DIR__ . '/../vendor/autoload.php';

// auto-load annotations
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

/**
 * Class AppKernel
 */
class AppKernel extends Kernel
{
    use MicroKernelTrait;

    ...

    protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
    {
        $researchConfig = Yaml::parse(file_get_contents(__DIR__ . '/config/research.yml'));
        $appExtension = new AppExtension();
        $appExtension->load(researchConfig, $c);

        $loader->load(__DIR__ . '/config/config.yml');
    }

    ...
}

然而,当我的 config.yml 看起来像这样时,我得到了上面提到的错误:

framework:
    secret: S0ME_SUPER_SECRET
    profiler: { only_exceptions: false }


research:
    questions:
       client_id: 2342323423
       clent_secret: mysecret

那么我需要做什么才能真正注册我的命名空间 research 以便我可以正确地覆盖它?还是外部供应商包?

你得到这个错误是因为你没有注册一个包,所以 symfony 不知道包配置命名空间。

我不能说你如何用你的方法解决这个问题,但我建议制作一个 AppBundle 而不是 App 并在 public function registerBundles().

中注册 AppBundle

参见f.E。在一些样板中,例如 https://github.com/ikoene/symfony-micro.

或者您可以尝试使用新的 symfony Flex 设置您的项目。
这已经使用了 MicroKernel,是无捆绑的并且还支持最新的稳定 symfony 版本 (sf3.3)。
https://symfony.com/doc/current/setup/flex.html#using-symfony-flex-in-new-applications

所以不需要自己在赛道外建造东西。

由于 Symfony 不再推荐使用 Bundle (),因此创建 Bundle 不是解决此问题的方法。

@见[https://symfony.com/doc/current/bundles.html][1]

In Symfony versions prior to 4.0, it was recommended to organize your own application code using bundles. This is no longer recommended and bundles should only be used to share code and features between multiple applications.

[1]:Symfony 捆绑文档