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
答案 0 :(得分:3)
如果ifTrue()
的值为algorithm
,您可以检查(使用md5
)。如果是这种情况,则取消设置包含原始配置值的数组中的blowfish
,sha256
,sha513
键。
如果algorithm
为blowfish
,sha256
或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();
你必须使用这样的东西:
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的way of doing it可能会引起人们的兴趣。
答案 1 :(得分:0)
这只是一个意见,也许只是一个愚蠢的答案......好吧,我们走了。
对于您的回答,我知道您已经了解/了解bundle extension的工作原理。
也许你可以定义configuring-services-and-setting-parameters
上所见的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()
...
...