Skip to content

Commit 4d04ccf

Browse files
committed
feature #5314 Documented the useAttributeAsKey() method (javiereguiluz)
This PR was merged into the 2.3 branch. Discussion ---------- Documented the useAttributeAsKey() method | Q | A | ------------- | --- | Doc fix? | no | New docs? | yes | Applies to | all | Fixed tickets | #4509 Two comments: * I've reordered the list of methods (addDefaultsIfNotSet, requiresAtLeastOneElement, useAttributeAsKey) to display it alphabetically and because it's better to have `useAttributeAsKey` at the end, just before showing the example. * I've left the XML code blocks empty and I'd like some XML expert to help me fill them. Commits ------- 9fe9020 Fixed a minor syntax issue e77c3b2 Rewritten the explanation about the useAttributeAsKey() method 0f8f9fd Documented the useAttributeAsKey() method
2 parents dd46bcd + 9fe9020 commit 4d04ccf

File tree

1 file changed

+130
-17
lines changed

1 file changed

+130
-17
lines changed

components/config/definition.rst

Lines changed: 130 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,44 +203,157 @@ Array Node Options
203203
Before defining the children of an array node, you can provide options like:
204204

205205
``useAttributeAsKey()``
206-
Provide the name of a child node, whose value should be used as the
207-
key in the resulting array.
206+
Provide the name of a child node, whose value should be used as the key in
207+
the resulting array. This method also defines the way config array keys are
208+
treated, as explained in the following example.
208209
``requiresAtLeastOneElement()``
209210
There should be at least one element in the array (works only when
210211
``isRequired()`` is also called).
211212
``addDefaultsIfNotSet()``
212213
If any child nodes have default values, use them if explicit values
213214
haven't been provided.
214215

215-
An example of this::
216+
A basic prototyped array configuration can be defined as follows::
216217

217-
$rootNode
218+
$node
219+
->fixXmlConfig('driver')
218220
->children()
219-
->arrayNode('parameters')
220-
->isRequired()
221-
->requiresAtLeastOneElement()
222-
->useAttributeAsKey('name')
221+
->arrayNode('drivers')
222+
->prototype('scalar')->end()
223+
->end()
224+
->end()
225+
;
226+
227+
When using the following YAML configuration:
228+
229+
.. code-block:: yaml
230+
231+
drivers: ['mysql', 'sqlite']
232+
233+
Or the following XML configuration:
234+
235+
.. code-block:: xml
236+
237+
<driver>msyql</driver>
238+
<driver>sqlite</driver>
239+
240+
The processed configuration is::
241+
242+
Array(
243+
[0] => 'mysql'
244+
[1] => 'sqlite'
245+
)
246+
247+
A more complex example would be to define a prototyped array with children::
248+
249+
$node
250+
->fixXmlConfig('connection')
251+
->children()
252+
->arrayNode('connections')
223253
->prototype('array')
224254
->children()
225-
->scalarNode('value')->isRequired()->end()
255+
->scalarNode('table')->end()
256+
->scalarNode('user')->end()
257+
->scalarNode('password')->end()
226258
->end()
227259
->end()
228260
->end()
229261
->end()
230262
;
231263

232-
In YAML, the configuration might look like this:
264+
When using the following YAML configuration:
233265

234266
.. code-block:: yaml
235267
236-
database:
237-
parameters:
238-
param1: { value: param1val }
268+
connections:
269+
- { table: symfony, user: root, password: ~ }
270+
- { table: foo, user: root, password: pa$$ }
271+
272+
Or the following XML configuration:
273+
274+
.. code-block:: xml
275+
276+
<connection table="symfony" user="root" password="null" />
277+
<connection table="foo" user="root" password="pa$$" />
278+
279+
The processed configuration is::
280+
281+
Array(
282+
[0] => Array(
283+
[table] => 'symfony'
284+
[user] => 'root'
285+
[password] => null
286+
)
287+
[1] => Array(
288+
[table] => 'foo'
289+
[user] => 'root'
290+
[password] => 'pa$$'
291+
)
292+
)
293+
294+
The previous output matches the expected result. However, given the configuration
295+
tree, when using the following YAML configuration:
296+
297+
.. code-block:: yaml
298+
299+
connections:
300+
sf_connection:
301+
table: symfony
302+
user: root
303+
password: ~
304+
default:
305+
table: foo
306+
user: root
307+
password: pa$$
308+
309+
The output configuration will be exactly the same as before. In other words, the
310+
``sf_connection`` and ``default`` configuration keys are lost. The reason is that
311+
the Symfony Config component treats arrays as lists by default.
312+
313+
In order to maintain the array keys use the ``useAttributeAsKey()`` method::
314+
315+
$node
316+
->fixXmlConfig('connection')
317+
->children()
318+
->arrayNode('connections')
319+
->prototype('array')
320+
->useAttributeAsKey('name')
321+
->children()
322+
->scalarNode('table')->end()
323+
->scalarNode('user')->end()
324+
->scalarNode('password')->end()
325+
->end()
326+
->end()
327+
->end()
328+
->end()
329+
;
330+
331+
The argument of this method (``name`` in the example above) defines the name of
332+
the attribute added to each XML node to differentiate them. Now you can use the
333+
same YAML configuration showed before or the following XML configuration:
334+
335+
.. code-block:: xml
239336
240-
In XML, each ``parameters`` node would have a ``name`` attribute (along
241-
with ``value``), which would be removed and used as the key for that element
242-
in the final array. The ``useAttributeAsKey`` is useful for normalizing
243-
how arrays are specified between different formats like XML and YAML.
337+
<connection name="sf_connection"
338+
table="symfony" user="root" password="null" />
339+
<connection name="default"
340+
table="foo" user="root" password="pa$$" />
341+
342+
In both cases, the processed configuration maintains the ``sf_connection`` and
343+
``default`` keys::
344+
345+
Array(
346+
[sf_connection] => Array(
347+
[table] => 'symfony'
348+
[user] => 'root'
349+
[password] => null
350+
)
351+
[default] => Array(
352+
[table] => 'foo'
353+
[user] => 'root'
354+
[password] => 'pa$$'
355+
)
356+
)
244357

245358
Default and Required Values
246359
---------------------------

0 commit comments

Comments
 (0)