如何动态地将部分附加到Symfony 2配置?

gre*_*emo 15 symfony

my_bundle:
    algorithm: blowfish # One of 'md5', 'blowfish', 'sha256', 'sha512'
Run Code Online (Sandbox Code Playgroud)

此配置由此配置树完成:

// Algorithms and constants to check
$algorithms = array(
    'md5'      => 'CRYPT_MD5',
    'blowfish' => 'CRYPT_BLOWFISH',
    'sha256'   => 'CRYPT_SHA256',
    'sha512'   => 'CRYPT_SHA512',
);

$rootNode
    ->children()
        ->scalarNode('algorithm')
            ->isRequired()
            ->beforeNormalization()
                ->ifString()
                ->then(function($v) { return strtolower($v); })
            ->end()
            ->validate()
                ->ifNotInArray(array_keys($algorithms))
                ->thenInvalid('invalid algorithm.')
            ->end()
            ->validate()
                ->ifTrue(function($v) use($algorithms) {
                    return 1 != @constant($algorithms[$v]);
                })
                ->thenInvalid('algorithm %s is not supported by this system.')
            ->end()
        ->end()
    ->end();
Run Code Online (Sandbox Code Playgroud)

由于每个算法都需要不同的参数,如何根据所选算法动态添加它们作为根节点的子节点?

例如,如果算法是"blowfish",那么应该有一个名为"cost"的标量节点,而如果"sha512"是一个标量节点"rounds",每个节点都有不同的验证规则.

编辑:我真正需要的是弄清楚当前的算法(如何处理$rootNode?)而不是调用:

$rootNode->append($this->getBlowfishParamsNode());
$rootNode->append($this->getSha256ParamsNode());
$rootNode->append($this->getSha512ParamsNode());
Run Code Online (Sandbox Code Playgroud)

编辑:我想要完成的可能配置:

my_bundle:
    algorithm: blowfish
    cost: 15
Run Code Online (Sandbox Code Playgroud)

另一个:

my_bundle:
    algorithm: sha512
    rounds: 50000
Run Code Online (Sandbox Code Playgroud)

而另一个:

my_bundle:
    algorithm: md5
Run Code Online (Sandbox Code Playgroud)

Mic*_*ick 3

您可以检查(使用ifTrue()) 的值是否algorithmmd5。如果是这种情况,请取消设置包含原始配置值的数组中的blowfish, sha256,键。sha513

然后,您可以使用类似的逻辑algorithmif blowfishsha256or sha513


$rootNode->
    ->beforeNormalization()
        //...
        ->ifTrue(function($v) {
            // $v contains the raw configuration values
            return 'md5' === $v['algorithm'];
        })
        ->then(function($v) {
            unset($v['blowfish']);
            unset($v['sha256']);
            unset($v['sha512']);
            return $v;
        })
        ->end()
        // ...do same logic for the others
    ->end();
Run Code Online (Sandbox Code Playgroud)

你必须使用这样的东西:

my_bundle:
    algorithm: blowfish
    md5: #your params
    blowfish: #will be unset if algorithm is md5 for example
    sha256: #will be unset if algorithm is md5 for example
    sha512: #will be unset if algorithm is md5 for example
Run Code Online (Sandbox Code Playgroud)

正如您所提到的,您可以附加所有这些:

$rootNode->append($this->getMd5ParamsNode());
$rootNode->append($this->getBlowfishParamsNode());
$rootNode->append($this->getSha256ParamsNode());
$rootNode->append($this->getSha512ParamsNode());
Run Code Online (Sandbox Code Playgroud)

编辑

还有一个thenUnset()功能。

编辑

这里可能对Doctrine 的做法感兴趣。