基本上我想在billings
节点下的配置中允许任意(但非空)数量的键值对定义关联数组。
我在Configurator.php
(部分):
->arrayNode('billings')
->isRequired()
->requiresAtLeastOneElement()
->prototype('scalar')
->end()
->end()
然后,在我的config.yml
:
my_bundle:
billings:
monthly : Monthly
bimonthly : Bimonthly
但是,输出$config
:
class MyBundleExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container,
new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);
$container->setParameter('my_bundle.billings', $config['billings']);
var_dump($config);
die();
}
}
...我得到的是数字索引,而不是关联数据:
'billings' =>
array (size=2)
0 => string 'Monthly' (length=7)
1 => string 'Bimonthly' (length=9)
出于好奇(如果这可以帮助),我正在尝试将此数组作为服务参数注入(来自这个伟大的包的注释:JMSDiExtraBundle):
class BillingType extends \Symfony\Component\Form\AbstractType
{
/**
* @var array
*/
private $billingChoices;
/**
* @InjectParams({"billingChoices" = @Inject("%billings%")})
*
* @param array $billingChoices
*/
public function __construct(array $billingChoices)
{
$this->billingChoices = $billingChoices;
}
}
答案 0 :(得分:24)
您应该在useAttributeAsKey('name')
。
Configurator.php
添加到您的结算节点配置中
有关useAttributeAsKey()
的更多信息,请参阅Symfony API Documentation
更改结算节点配置后,它应该是:
->arrayNode('billings')
->isRequired()
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
答案 1 :(得分:2)
您可以添加以下内容:
->arrayNode('billings')
->useAttributeAsKey('whatever')
->prototype('scalar')->end()
之后,键会神奇地出现。
答案 2 :(得分:2)
我最近不得不设置一些嵌套数组配置。
需求
要实现这样的配置,您必须使用prototype()
方法。
所以,以下配置:
my_bundle:
some_scalar: my_scalar_value
first_level:
"AppBundle:User":
first_tag: false
"AppBundle:Admin":
second_tag: true
third_tag: false
可以使用以下配置获得:
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_bundle');
$rootNode
->addDefaultsIfNotSet() # may or may not apply to your needs
->performNoDeepMerging() # may or may not apply to your needs
->children()
->scalarNode('some_scalar')
->info("Some useful tips ..")
->defaultValue('default')
->end()
->arrayNode('first_level')
->info('Useful tips here..')
# first_level expects its children to be arrays
# with arbitrary key names
->prototype('array')
# Those arrays are expected to hold one or more boolean entr(y|ies)
# with arbitrary key names
->prototype('boolean')
->defaultFalse()->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
从扩展类中转储$ config会得到以下输出:
Array
(
[some_scalar] => my_scalar_value
[first_level] => Array
(
[AppBundle:User] => Array
(
[first_tag] =>
)
[AppBundle:Admin] => Array
(
[second_tag] => 1
[third_tag] =>
)
)
)
瞧!
答案 3 :(得分:0)
useAttributeAsKey
实际上是这样做的:
/**
* Sets the attribute which value is to be used as key.
*
* This is useful when you have an indexed array that should be an
* associative array. You can select an item from within the array
* to be the key of the particular item. For example, if "id" is the
* "key", then:
*
* array(
* array('id' => 'my_name', 'foo' => 'bar'),
* );
*
* becomes
*
* array(
* 'my_name' => array('foo' => 'bar'),
* );
*
* If you'd like "'id' => 'my_name'" to still be present in the resulting
* array, then you can set the second argument of this method to false.
*
* This method is applicable to prototype nodes only.
*
* @param string $name The name of the key
* @param bool $removeKeyItem Whether or not the key item should be removed
*
* @return ArrayNodeDefinition
*/
public function useAttributeAsKey($name, $removeKeyItem = true)
{
$this->key = $name;
$this->removeKeyItem = $removeKeyItem;
return $this;
}