-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -200,43 +200,158 @@ Array Node Options | |
|
||
Before defining the children of an array node, you can provide options like: | ||
|
||
``useAttributeAsKey()`` | ||
Provide the name of a child node, whose value should be used as the key in the resulting array. | ||
``requiresAtLeastOneElement()`` | ||
There should be at least one element in the array (works only when ``isRequired()`` is also | ||
called). | ||
``addDefaultsIfNotSet()`` | ||
If any child nodes have default values, use them if explicit values haven't been provided. | ||
If any child nodes have default values, use them if explicit values haven't | ||
been provided. | ||
``requiresAtLeastOneElement()`` | ||
There should be at least one element in the array (works only when | ||
``isRequired()`` is also called). | ||
``useAttributeAsKey()`` | ||
Provide the name of a child node, whose value should be used as the key in | ||
the resulting array. This method also defines the way config array keys are | ||
treated, as explained in the following example. | ||
|
||
An example of this:: | ||
A basic prototyped array configuration can be defined as follows:: | ||
|
||
$rootNode | ||
$node | ||
->fixXmlConfig('driver') | ||
->children() | ||
->arrayNode('parameters') | ||
->isRequired() | ||
->requiresAtLeastOneElement() | ||
->useAttributeAsKey('name') | ||
->arrayNode('drivers') | ||
->prototype('scalar')->end() | ||
->end() | ||
->end() | ||
; | ||
|
||
When using the following YAML configuration: | ||
|
||
.. code-block:: yaml | ||
|
||
drivers: ['mysql', 'sqlite'] | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this also possible? drivers:
- mysql
- sqlite There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, but we don't want to write this example explicitly, too? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 :) |
||
Or the following XML configuration: | ||
|
||
.. code-block:: xml | ||
|
||
<driver>msyql</driver> | ||
<driver>sqlite</driver> | ||
|
||
The processed configuration is:: | ||
|
||
Array( | ||
[0] => 'mysql' | ||
[1] => 'sqlite' | ||
) | ||
|
||
A more complex example would be to define a prototyped array with children:: | ||
|
||
$node | ||
->fixXmlConfig('connection') | ||
->children() | ||
->arrayNode('connections') | ||
->prototype('array') | ||
->children() | ||
->scalarNode('value')->isRequired()->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: | ||
param1: { value: param1val } | ||
connections: | ||
- { table: symfony, user: root, password: ~ } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the example, i would prefer |
||
- { table: foo, user: root, password: pa$$ } | ||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that actually true when using the YAML format? Isn't the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 would have a ``name`` attribute (along with | ||
``value``), which would be removed and used as the key for that element in | ||
the final array. The ``useAttributeAsKey`` 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 | ||
--------------------------- | ||
|
There was a problem hiding this comment.
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
andpdo_mysql
, cause they were used in doctrine?There was a problem hiding this comment.
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)