Конфигурация node поддерживает как строку, так и массив в конфигурации Symfony 2?
Может ли моя конфигурация node source
поддерживать значения string
и array
?
Поиск из string
:
# Valid configuration 1
my_bundle:
source: %kernel.root_dir%/../Resources/config/source.json
Поиск из array
:
# Valid configuration 2
my_bundle:
source:
operations: []
commands: []
Класс расширения мог бы различать между ними:
if (is_array($config['source']) {
// Bootstrap from array
} else {
// Bootstrap from file
}
Я мог бы использовать что-то вроде этого:
$rootNode->children()
->variableNode('source')
->validate()
->ifTrue(function ($v) { return !is_string($v) && !is_array($v); })
->thenInvalid('Configuration value must be either string or array.')
->end()
->end()
->end();
Но как я добавляю ограничения на структуру source
(операции, команды и т.д.) на переменную node (ее следует применять только тогда, когда ее значение имеет тип array
)?
Ответы
Ответ 1
Я думаю, вы можете использовать нормализацию конфигурации путем рефакторинга своего расширения.
В своем расширении измените свой код, чтобы проверить, установлен ли путь
if ($config['path'] !== null) {
// Bootstrap from file.
} else {
// Bootstrap from array.
}
И разрешите пользователю использовать строку для конфигурации.
$rootNode
->children()
->arrayNode('source')
->beforeNormalization()
->ifString()
->then(function($value) { return array('path' => $value); })
->end()
->children()
->scalarNode('foo')
// ...
->end()
->end()
->end()
;
Подобным образом вы можете разрешить пользователю использовать строку или массив, которые могут быть проверены.
См. документацию Symfony для нормализации.
Надеюсь, это полезно.
Наилучшее отношение.
Ответ 2
Можно использовать тип variable node в сочетании с некоторой пользовательской логикой проверки:
<?php
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_bundle');
$rootNode
->children()
->variableNode('source')
->validate()
->ifTrue(function ($v) {
return false === is_string($v) && false === is_array($v);
})
->thenInvalid('Here you message about why it is invalid')
->end()
->end()
->end();
;
return $treeBuilder;
}
Это будет успешно выполнено:
my_bundle:
source: foo
# and
my_bundle:
source: [foo, bar]
но он не будет обрабатываться:
my_bundle:
source: 1
# or
my_bundle
source: ~
Конечно, вы не получите правильные правила проверки, которые нормальная конфигурация node предоставит вам, и вы не сможете использовать эти правила проверки для массива (или строки), но вы сможете подтвердите переданные данные в используемом закрытии.