Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

php - How to define dynamic configuration using the TreeBuilder?

I want to configure a bundle to allow different behavior for different companies. The config structure within them will be the same.

My config.yml shall look like this:

bunde_namespace:
    company:
        company_1:
            foo: bar
            baz: poit
        company_2:
            foo: bar
            baz: poit
        company_3:
            ...

When I access the $config I expect the array to look something like this:

$config['company'] = [
    'company_one' => [
        'foo' => 'bar'
        'baz' => 'poit'
    ],
    'company_two' => [
        'foo' => 'bar'
        'baz' => 'poit'
    ],
    ...
];

Yet I have no experience with the TreeBuilder and setting up the configuration as described in the docs and it still eludes me as to how I setup my configuration so that it treats the children of company as keyed arrays.

What I achieved so far is to setup the config for one company, like so:

class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('dreamlines_booking_service_fibos');

        $rootNode
            ->children()
            ->arrayNode('company')
                ->children()
                    ->scalarNode('foo')->end()
                    ->scalarNode('baz')->end()
                    ->end()
                ->end()
        ->end();

        return $treeBuilder;
    }
}

And the simplified config.yml would look like this:

bundle_namespace:
    company:
        foo: bar
        baz: poit

Yet this is not what I want.

I am assuming that I need to use useAttributeAsKey yet I have trouble getting it work.

This fails:

    $rootNode
        ->children()
        ->arrayNode('company')
            ->prototype('array')
            ->useAttributeAsKey('name')
            ->children()
                    ->scalarNode('foo')->end()
                    ->scalarNode('baz')->end()
                ->end()
           ->end()
        ->end()
    ->end();

stating:

[SymfonyComponentConfigDefinitionExceptionInvalidDefinitionException] ->useAttributeAsKey() is not applicable to concrete nodes at path "bundle_namespace."

Where am I going wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The error you get is caused when you try to apply useAttributeAsKey on a prototype, but since the method is a part of the ArrayNodeDefinition, it needs to be added right after ->arrayNode(...). Try it this way, and the error will disappear.

Now, if I understood your question correctly, the following output is the one you aim for:

Array
(
    [company] => Array
        (
            [company_1] => Array
                (
                    [foo] => bar
                    [baz] => baz
                )

            [company_2] => Array
                (
                    [foo] => bar
                    [baz] => baz
                )

        )

)

which you can achieve with the following structure:

$rootNode
        ->children()
            ->arrayNode('company')
                ->prototype('array')
                    ->children()
                        ->scalarNode('foo')->end()
                        ->scalarNode('baz')->end()
                    ->end()
                ->end()
            ->end()
        ->end()
    ;

the configuration loaded:

app:
    company:
        company_1:
            foo: bar
            baz: baz
        company_2:
            foo: bar
            baz: baz

Please, include a comment if I misunderstood your question.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...