15
my_bundle:
    algorithm: blowfish # One of 'md5', 'blowfish', 'sha256', 'sha512'

此配置由此配置树完成:

// 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();

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

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

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

$rootNode->append($this->getBlowfishParamsNode());
$rootNode->append($this->getSha256ParamsNode());
$rootNode->append($this->getSha512ParamsNode());

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

my_bundle:
    algorithm: blowfish
    cost: 15

其他:

my_bundle:
    algorithm: sha512
    rounds: 50000

还有一个:

my_bundle:
    algorithm: md5
4

2 回答 2

3

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

然后,您可以使用类似的逻辑 if algorithmis或。blowfishsha256sha513


$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();

你必须使用这样的东西:

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

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

$rootNode->append($this->getMd5ParamsNode());
$rootNode->append($this->getBlowfishParamsNode());
$rootNode->append($this->getSha256ParamsNode());
$rootNode->append($this->getSha512ParamsNode());

编辑

还有一个thenUnset()功能。

编辑

Doctrine 的做法在这里可能很有趣。

于 2013-02-06T15:41:20.967 回答
0

Gremo,也许我在这里走错了路。顺便说一句,感谢您对我的问题的答复。

它只是一个意见,也许它只是一个愚蠢的答案......好吧,我们开始吧。

对于您的回答,我知道您已经知道/了解捆绑扩展的工作原理。

也许您可以定义所需的 4 个空参数,如配置服务和设置参数中所见

...您将根据传入的配置值在扩展类中设置此参数...

然后您可以对树进行特定检查(例如,如果算法是“河豚”,则需要成本)

$rootNode->
    ->beforeNormalization()
        ->ifTrue(function($v) {
            // $v contains the raw configuration values
            // if 'algorithm' blowfish -> cost isRequired
            // or as you said on your question you can call
            // ->append($this->addBlowfishParametersNode())
        })
        ->then(function($v) {
            // maybe some unsetting, but not needed
        })
        ->end()
    ->children()
        // ...
    ->end()
;

检查“附加部分

public function addBlowfishParametersNode()
{
    $builder = new TreeBuilder();
    $node = $builder->root('parameters');

    $node
        ->isRequired()
        ->requiresAtLeastOneElement()
        ...
        ...
于 2013-02-07T23:21:03.473 回答