【问题标题】:Getting errors when validating Symfony2 semantic configuration验证 Symfony2 语义配置时出错
【发布时间】:2014-08-15 18:51:14
【问题描述】:

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

spu:
    modules:
        spu-module:
            reuqires: []
            path: modules/spu-module.js

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

namespace Gig\SpuBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;


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' );
        $loader->load( 'spu.yml' );
    }
}

而这个扩展的配置类()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”处的子节点“modules”。

我做错了什么?

【问题讨论】:

    标签: php symfony configuration dependency-injection


    【解决方案1】:

    您必须将它包含在您的主 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();
    

    【讨论】:

    【解决方案2】:

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

    您可以保留您在 Configuration 类中的配置,但您必须修改您的 spuExtension 类。

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

    这就是你的 config.yml 的样子

    spu:
        modules:
            spu-module:
                reuqires: []
                path: modules/spu-module.js
    

    然后在您的 spuExtension 类中,您可以通过以下方式获取这些值:

    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]);
    }
    

    }

    这将使您可以轻松地在控制器中使用容器来获取参数。

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

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

    【讨论】:

    • 在我的例子中 $configs[0] 是一个空数组
    • 你把配置移到 config.yml 了吗?
    • 否,因为据我所知,每个包都应该有单独的配置,我想使用语义配置并验证参数:symfony.com/doc/current/cookbook/bundles/extension.html
    • 正如您在同一页面上看到的那样,您链接的每个配置都应该驻留在 config.yml 文件中。该文件具有不同的名称空间,其中包括您的名称空间(spu)。这就是 Symfony 的工作原理,我真的不明白为什么每个包都应该有一个单独的配置文件,因为我根本看不到该页面上列出的配置文件。
    • 我想您希望用户能够编辑这些配置,对吧?如果不是,则没有理由单独配置文件。如果你这样做,那么最好将它放入 config.yml 因为如果你这样做,用户应该创建另一个 spu.yml 但你的加载器不会加载它。长话短说,如果您希望用户能够覆盖这些配置,只需使用 config.yml,因为它应该是这样工作的。如果外部用户不应该能够编辑这些配置,那你为什么还要这些配置呢?
    【解决方案3】:

    好的,我用不同的方式做的。

    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 );
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多