10000 Documented the useAttributeAsKey() method by javiereguiluz · Pull Request #5314 · symfony/symfony-docs · GitHub
[go: up one dir, main page]

Skip to content

Documented the useAttributeAsKey() method #5314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 14, 2015
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rewritten the explanation about the useAttributeAsKey() method
  • Loading branch information
javiereguiluz committed May 25, 2015
commit e77c3b28e8c78863f97e202f2d4709a50dc347b1
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']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use pdo_sqlite and pdo_mysql, cause they were used in doctrine?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example isn't about doctrine, I choose a different value on purpose (honestly, I didn't want to take databases as an example, but couldn't come up with something else)


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this also possible?

drivers:
  - mysql
  - sqlite

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it is, because this is exactly the same in YAML, so the Config component receives the same input.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, but we don't want to write this example explicitly, too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no need in doing that, this chapter is teaching you the Config component, not the Yaml syntax :)

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: ~ }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the example, i would prefer database instead of table

- { 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that actually true when using the YAML format? Isn't the useAttributeAsKey() method only necessary when using the XML format because XML itself does not know anything like hashes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh actually, there is an inconsistency in Symfony currently: if we need to merge lists coming from multiple files, the keys are lost (merging them in a new list indexed numerically). However, in case merging is not necessary (a single file configures this list), we currently don't reset keys


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="n 67ED ull" />
<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