Php 验证Symfony2语义配置时出错

Php 验证Symfony2语义配置时出错,php,symfony,configuration,dependency-injection,Php,Symfony,Configuration,Dependency Injection,我正在尝试用Symfony2编写包的语义配置。我已经使用YAML(spu.yml)准备了一个配置文件: 然后我将其加载到扩展文件(DependencyInjection/sputextension.php)中: 此扩展的配置类()DependencyInjection/configuration.php)是: namespace Gig\SpuBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\

我正在尝试用Symfony2编写包的语义配置。我已经使用YAML(spu.yml)准备了一个配置文件:

然后我将其加载到扩展文件(DependencyInjection/sputextension.php)中:

此扩展的配置类()DependencyInjection/configuration.php)是:

namespace Gig\SpuBundle\DependencyInjection;

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

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

        $rootNode
            ->children()
                ->arrayNode('modules')
                    ->isRequired()
                    ->prototype('array')
                ->end()
            ->end();

        return $treeBuilder;
    }
}
验证配置时,我收到一个错误:

[Symfony\Component\Config\Definition\Exception\InvalidConfigurationException] 必须配置路径“spu”处的子节点“模块”


我做错了什么?

您必须将其包含在主app/config/config.yml文件中

imports:
  - { resource: parameters.yml }
  - { resource: security.yml }
  - { resource: spu.yml }
如果希望有默认参数,请在DependencyInjection/Configuration.php中设置它们 这可能是这样的

$rootNode
    ->children()
        ->arrayNode('modules')
            ->isRequired()
            ->addDefaultsIfNotSet()         
            ->prototype('array')
            ->children()
                ->arrayNode('reuqires')->end()
                ->scalarNode('path')->defaultValue('modules/spu-module.js')->end()
            ->end()
        ->end()
    ->end()
->end();

最好的方法是让用户在config.yml文件中定义包的配置。不需要特殊的文件

您可以保留配置类中的配置,但必须修改扩展类

按照Symfony的工作方式,您必须从config.yml中读取SPU扩展类中捆绑包的值,然后将它们设置为参数。然后,通过使用容器的getParameter方法可以轻松访问这些值

这就是config.yml的外观

spu:
    modules:
        spu-module:
            reuqires: []
            path: modules/spu-module.js
然后,在SPU扩展类中,您可以通过执行以下操作来获得指定的值:

class spuExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
    $configuration = new Configuration();
    $config = $this->processConfiguration( $configuration, $configs );

    $loader = new Loader\YamlFileLoader( $container, new FileLocator( __DIR__ .     '/../Resources/config' ) );
    $loader->load( 'services.yml' );

    $container->setParameter('modules', $configs[0]);
}
}

这将使您很容易使用控制器中的容器来获取参数

SPU扩展中的$configs变量将包含根目录下列出的所有配置。在这种情况下是spu


Symfony的工作方式您首先必须在bundle的扩展类中加载配置,然后将其设置为一个参数,这似乎是多余的,但这是一个最佳实践,它的目的是这样工作。

好的,我采用了不同的方式

$rootNode
    ->children()
        ->arrayNode('modules')
            ->isRequired()
            ->addDefaultsIfNotSet()         
            ->prototype('array')
            ->children()
                ->arrayNode('reuqires')->end()
                ->scalarNode('path')->defaultValue('modules/spu-module.js')->end()
            ->end()
        ->end()
    ->end()
->end();
public function load(array $configs, ContainerBuilder $container)
{
    $loader = new Loader\YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
    $loader->load( 'services.yml' );
    $loader->load( 'spu.yml' );

    $spuConfig  = Yaml::parse(__DIR__ . '/../Resources/config/spu.yml');
    $configs    = array_merge($configs, $spuConfig);

    $configuration = new Configuration();
    $config = $this->processConfiguration( $configuration, $configs );
}

现在我得到了我想要的。我可以在
配置
类中验证参数。

但是我正在开发第三方包,我希望它能够自动安装。有必要吗?还有其他方法吗?您可能应该阅读有关配置组件的doku,以便更好地理解:在我的情况下,
$configs[0]
是一个空阵列您是否已将配置移动到config.yml?没有,因为据我所知,每个捆绑包都应该有单独的配置,我想使用语义配置和验证参数:正如您在链接的同一页面上看到的,每个配置都应该位于config.yml文件中。该文件具有不同的名称空间,其中包括您的名称空间(spu)。这就是Symfony的工作原理,我真的不明白为什么每个捆绑包都应该有一个单独的配置文件,因为我根本看不到该页面上列出的配置文件。我猜想您希望用户能够编辑这些配置,对吗?如果没有,就没有理由使用单独的配置文件。如果您这样做,那么最好将其放入config.yml,因为如果您这样做,用户应该创建另一个spu.yml,但您的加载程序不会加载它。长话短说,如果您希望用户能够覆盖这些配置,只需使用config.yml,因为它应该是这样工作的。如果外部用户不能编辑这些配置,那么您为什么还要这些配置?
public function load(array $configs, ContainerBuilder $container)
{
    $loader = new Loader\YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
    $loader->load( 'services.yml' );
    $loader->load( 'spu.yml' );

    $spuConfig  = Yaml::parse(__DIR__ . '/../Resources/config/spu.yml');
    $configs    = array_merge($configs, $spuConfig);

    $configuration = new Configuration();
    $config = $this->processConfiguration( $configuration, $configs );
}