Skip to content

Commit

Permalink
Rewritten the explanation about the useAttributeAsKey() method
Browse files Browse the repository at this point in the history
  • Loading branch information
javiereguiluz committed May 25, 2015
1 parent 0f8f9fd commit e77c3b2
Showing 1 changed file with 109 additions and 34 deletions.
143 changes: 109 additions & 34 deletions components/config/definition.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,72 +211,147 @@ Before defining the children of an array node, you can provide options like:
the resulting array. This method also defines the way config array keys are
treated, as explained in the following example.

When the ``useAttributeAsKey()`` method is not used, the names of the array
elements (i.e. the array keys) are ignored when parsing the configuration.
Consider this example::
A basic prototyped array configuration can be defined as follows::

$rootNode
$node
->fixXmlConfig('driver')
->children()
->arrayNode('parameters')
->prototype('array')
->children()
->scalarNode('parameter1')->end()
->scalarNode('parameter2')->end()
->end()
->end()
->arrayNode('drivers')
->prototype('scalar')->end()
->end()
->end()
;

In YAML, the configuration might look like this:
When using the following YAML configuration:

.. code-block:: yaml
database:
parameters: [ 'value1', 'value2' ]
drivers: ['mysql', 'sqlite']
In XML, the configuration might look like this:
Or the following XML configuration:

.. code-block:: xml
...
<driver>msyql</driver>
<driver>sqlite</driver>
However, if the ``useAttributeAsKey()`` method is set, the parsed configuration
will be completely different::
The processed configuration is::

$rootNode
Array(
[0] => 'mysql'
[1] => 'sqlite'
)

A more complex example would be to define a prototyped array with children:

$node
->fixXmlConfig('connection')
->children()
->arrayNode('parameters')
->useAttributeAsKey('value')
->arrayNode('connections')
->prototype('array')
->children()
->scalarNode('parameter1')->end()
->scalarNode('parameter2')->end()
->scalarNode('table')->end()
->scalarNode('user')->end()
->scalarNode('password')->end()
->end()
->end()
->end()
->end()
;

In YAML, the configuration might look like this:
When using the following YAML configuration:

.. code-block:: yaml
database:
parameters:
parameter1: { value: 'value1' }
parameter2: { value: 'value2' }
connections:
- { table: symfony, user: root, password: ~ }
- { table: foo, user: root, password: pa$$ }
In XML, the configuration might look like this:
Or the following XML configuration:

.. code-block:: xml
...
<connection table="symfony" user="root" password="null" />
<connection table="foo" user="root" password="pa$$" />
The processed configuration is::

Array(
[0] => Array(
[table] => 'symfony'
[user] => 'root'
[password] => null
)
[1] => Array(
[table] => 'foo'
[user] => 'root'
[password] => 'pa$$'
)
)

The previous output matches the expected result. However, given the configuration
tree, when using the following YAML configuration:

.. code-block:: yaml
connections:
sf_connection:
table: symfony
user: root
password: ~
default:
table: foo
user: root
password: pa$$
The output configuration will be exactly the same as before. In other words, the
``sf_connection`` and ``default`` configuration keys are lost. The reason is that
the Symfony Config component treats arrays as lists by default.

In order to maintain the array keys use the ``useAttributeAsKey()`` method::

$node
->fixXmlConfig('connection')
->children()
->arrayNode('connections')
->prototype('array')
->useAttributeAsKey('name')
->children()
->scalarNode('table')->end()
->scalarNode('user')->end()
->scalarNode('password')->end()
->end()
->end()
->end()
->end()
;

The argument of this method (``name`` in the example above) defines the name of
the attribute added to each XML node to differentiate them. Now you can use the
same YAML configuration showed before or the following XML configuration:

.. code-block:: xml
In XML, each ``parameters`` node has a ``value`` attribute (along with
``value``), which would be removed and used as the key for that element in
the final array. The ``useAttributeAsKey()`` method is useful for normalizing
how arrays are specified between different formats like XML and YAML.
<connection name="sf_connection"
table="symfony" user="root" password="null" />
<connection name="default"
table="foo" user="root" password="pa$$" />
In both cases, the processed configuration maintains the ``sf_connection`` and
``default`` keys::

Array(
[sf_connection] => Array(
[table] => 'symfony'
[user] => 'root'
[password] => null
)
[default] => Array(
[table] => 'foo'
[user] => 'root'
[password] => 'pa$$'
)
)

Default and required Values
---------------------------
Expand Down

0 comments on commit e77c3b2

Please sign in to comment.