Skip to content

Commit 22b9b27

Browse files
committed
minor #4372 Tweaks after proofreading the 2.6 OptionsResolver stuff (weaverryan, WouterJ)
This PR was merged into the master branch. Discussion ---------- Tweaks after proofreading the 2.6 OptionsResolver stuff Hi guys! This is a proofread after merging #4159. There were enough changes there that the easiest way to handle things was to merge, re-read entirely, then open a PR with small tweaks. But largely, I am very happy with how the document turned out :). | Q | A | ------------- | --- | Doc fix? | yes | New docs? | no | Applies to | 2.6+ | Fixed tickets | -- Thanks! Commits ------- b49731b Linking to the 2.6 headline thanks to a suggestion from @xabbuh a1badc5 Renaming a method at the suggestion of my friend Bernhard f179ec7 A few more tweaks from comments 59fd436 Also did a quick proofread d190831 Tweaks after proofreading the 2.6 OptionsResolver stuff
2 parents 90bc241 + b49731b commit 22b9b27

File tree

1 file changed

+60
-38
lines changed

1 file changed

+60
-38
lines changed

components/options_resolver.rst

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
The OptionsResolver Component
66
=============================
77

8-
The OptionsResolver component is `array_replace()` on steroids.
8+
The OptionsResolver component is :phpfunction:`array_replace` on steroids.
9+
It allows you to create an options system with required options, defaults,
10+
validation (type, value), normalization and more.
911

1012
Installation
1113
------------
@@ -20,8 +22,8 @@ Notes on Previous Versions
2022

2123
.. versionadded:: 2.6
2224
This documentation was written for Symfony 2.6 and later. If you use an older
23-
version, please read the corresponding documentation using the version
24-
drop-down on the upper right.
25+
version, please `read the Symfony 2.5 documentation`_. For a list of changes,
26+
see the `CHANGELOG`_.
2527

2628
Usage
2729
-----
@@ -48,29 +50,35 @@ check which options are set::
4850
public function sendMail($from, $to)
4951
{
5052
$mail = ...;
53+
5154
$mail->setHost(isset($this->options['host'])
5255
? $this->options['host']
5356
: 'smtp.example.org');
57+
5458
$mail->setUsername(isset($this->options['username'])
5559
? $this->options['username']
5660
: 'user');
61+
5762
$mail->setPassword(isset($this->options['password'])
5863
? $this->options['password']
5964
: 'pa$$word');
65+
6066
$mail->setPort(isset($this->options['port'])
6167
? $this->options['port']
6268
: 25);
69+
6370
// ...
6471
}
6572
}
6673

6774
This boilerplate is hard to read and repetitive. Also, the default values of the
68-
options are buried in the business logic of your code. We can use
75+
options are buried in the business logic of your code. Use the
6976
:phpfunction:`array_replace` to fix that::
7077

7178
class Mailer
7279
{
7380
// ...
81+
7482
public function __construct(array $options = array())
7583
{
7684
$this->options = array_replace(array(
@@ -83,27 +91,27 @@ options are buried in the business logic of your code. We can use
8391
}
8492

8593
Now all four options are guaranteed to be set. But what happens if the user of
86-
the ``Mailer`` class does a mistake?
94+
the ``Mailer`` class makes a mistake?
8795

8896
.. code-block:: php
8997
9098
$mailer = new Mailer(array(
9199
'usernme' => 'johndoe',
92100
));
93101
94-
No error will be shown. In the best case, the bug will be appear during testing.
95-
The developer will possibly spend a lot of time looking for the problem. In the
96-
worst case, however, the bug won't even appear and will be deployed to the live
97-
system.
102+
No error will be shown. In the best case, the bug will appear during testing,
103+
but the developer will spend time looking for the problem. In the worst case,
104+
the bug might not appear until it's deployed to the live system.
98105

99-
Let's use the :class:`Symfony\\Component\\OptionsResolver\\OptionsResolver`
100-
class to fix this problem::
106+
Fortunately, the :class:`Symfony\\Component\\OptionsResolver\\OptionsResolver`
107+
class helps you to fix this problem::
101108

102109
use Symfony\Component\OptionsResolver\Options;
103110

104111
class Mailer
105112
{
106113
// ...
114+
107115
public function __construct(array $options = array())
108116
{
109117
$resolver = new OptionsResolver();
@@ -136,6 +144,7 @@ code::
136144
class Mailer
137145
{
138146
// ...
147+
139148
public function sendMail($from, $to)
140149
{
141150
$mail = ...;
@@ -153,6 +162,7 @@ It's a good practice to split the option configuration into a separate method::
153162
class Mailer
154163
{
155164
// ...
165+
156166
public function __construct(array $options = array())
157167
{
158168
$resolver = new OptionsResolver();
@@ -164,10 +174,10 @@ It's a good practice to split the option configuration into a separate method::
164174
protected function configureOptions(OptionsResolver $resolver)
165175
{
166176
$resolver->setDefaults(array(
167-
'host' => 'smtp.example.org',
168-
'username' => 'user',
169-
'password' => 'pa$$word',
170-
'port' => 25,
177+
'host' => 'smtp.example.org',
178+
'username' => 'user',
179+
'password' => 'pa$$word',
180+
'port' => 25,
171181
'encryption' => null,
172182
));
173183
}
@@ -196,12 +206,13 @@ Required Options
196206

197207
If an option must be set by the caller, pass that option to
198208
:method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setRequired`.
199-
For example, let's make the ``host`` option required::
209+
For example, to make the ``host`` option required, you can do::
200210

201211
// ...
202212
class Mailer
203213
{
204214
// ...
215+
205216
protected function configureOptions(OptionsResolver $resolver)
206217
{
207218
// ...
@@ -210,8 +221,8 @@ For example, let's make the ``host`` option required::
210221
}
211222

212223
.. versionadded:: 2.6
213-
Before Symfony 2.6, `setRequired()` accepted only arrays. Since then, single
214-
option names can be passed as well.
224+
As of Symfony 2.6, ``setRequired()`` accepts both an array of options or a
225+
single option. Prior to 2.6, you could only pass arrays.
215226

216227
If you omit a required option, a
217228
:class:`Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException`
@@ -229,6 +240,7 @@ one required option::
229240
class Mailer
230241
{
231242
// ...
243+
232244
protected function configureOptions(OptionsResolver $resolver)
233245
{
234246
// ...
@@ -268,14 +280,15 @@ retrieve the names of all required options::
268280

269281
If you want to check whether a required option is still missing from the default
270282
options, you can use :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::isMissing`.
271-
The difference to :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::isRequired`
272-
is that this method will return false for required options that have already
283+
The difference between this and :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::isRequired`
284+
is that this method will return false if a required option has already
273285
been set::
274286

275287
// ...
276288
class Mailer
277289
{
278290
// ...
291+
279292
protected function configureOptions(OptionsResolver $resolver)
280293
{
281294
// ...
@@ -320,6 +333,7 @@ correctly. To validate the types of the options, call
320333
class Mailer
321334
{
322335
// ...
336+
323337
protected function configureOptions(OptionsResolver $resolver)
324338
{
325339
// ...
@@ -329,8 +343,8 @@ correctly. To validate the types of the options, call
329343
}
330344

331345
For each option, you can define either just one type or an array of acceptable
332-
types. You can pass any type for which an ``is_<type>()`` method is defined.
333-
Additionally, you may pass fully qualified class or interface names.
346+
types. You can pass any type for which an ``is_<type>()`` function is defined
347+
in PHP. Additionally, you may pass fully qualified class or interface names.
334348

335349
If you pass an invalid option now, an
336350
:class:`Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException`
@@ -348,9 +362,7 @@ to add additional allowed types without erasing the ones already set.
348362

349363
.. versionadded:: 2.6
350364
Before Symfony 2.6, `setAllowedTypes()` and `addAllowedTypes()` expected
351-
the values to be given as an array mapping option names to allowed types:
352-
353-
.. code-block:: php
365+
the values to be given as an array mapping option names to allowed types::
354366

355367
$resolver->setAllowedTypes(array('port' => array('null', 'int')));
356368

@@ -360,13 +372,14 @@ Value Validation
360372
Some options can only take one of a fixed list of predefined values. For
361373
example, suppose the ``Mailer`` class has a ``transport`` option which can be
362374
one of ``sendmail``, ``mail`` and ``smtp``. Use the method
363-
:method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setAllowedValues` to verify
364-
that the passed option contains one of these values::
375+
:method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setAllowedValues`
376+
to verify that the passed option contains one of these values::
365377

366378
// ...
367379
class Mailer
368380
{
369381
// ...
382+
370383
protected function configureOptions(OptionsResolver $resolver)
371384
{
372385
// ...
@@ -420,9 +433,11 @@ option. You can configure a normalizer by calling
420433
class Mailer
421434
{
422435
// ...
436+
423437
protected function configureOptions(OptionsResolver $resolver)
424438
{
425439
// ...
440+
426441
$resolver->setNormalizer('host', function ($options, $value) {
427442
if ('http://' !== substr($value, 0, 7)) {
428443
$value = 'http://'.$value;
@@ -467,12 +482,12 @@ Default Values that Depend on another Option
467482
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
468483

469484
Suppose you want to set the default value of the ``port`` option based on the
470-
encryption chosen by the user of the ``Mailer`` class. More precisely, we want
485+
encryption chosen by the user of the ``Mailer`` class. More precisely, you want
471486
to set the port to ``465`` if SSL is used and to ``25`` otherwise.
472487

473-
You can implement this feature by passing a closure as default value of the
474-
``port`` option. The closure receives the options as argument. Based on these
475-
options, you can return the desired default value::
488+
You can implement this feature by passing a closure as the default value of
489+
the ``port`` option. The closure receives the options as argument. Based on
490+
these options, you can return the desired default value::
476491

477492
use Symfony\Component\OptionsResolver\Options;
478493

@@ -498,7 +513,7 @@ options, you can return the desired default value::
498513
.. caution::
499514

500515
The argument of the callable must be type hinted as ``Options``. Otherwise,
501-
the callable is considered as the default value of the option.
516+
the callable itself is considered as the default value of the option.
502517

503518
.. note::
504519

@@ -546,8 +561,10 @@ Options without Default Values
546561
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
547562

548563
In some cases, it is useful to define an option without setting a default value.
549-
Mostly, you will need this when you want to know whether an option was passed
550-
or not. If you set a default value for that option, this is not possible::
564+
This is useful if you need to know whether or not the user *actually* set
565+
an option or not. For example, if you set the default value for an option,
566+
it's not possible to know whether the user passed this value or if it simply
567+
comes from the default::
551568

552569
// ...
553570
class Mailer
@@ -584,6 +601,7 @@ be included in the resolved options if it was actually passed to
584601
class Mailer
585602
{
586603
// ...
604+
587605
protected function configureOptions(OptionsResolver $resolver)
588606
{
589607
// ...
@@ -637,6 +655,8 @@ let you find out which options are defined::
637655
// ...
638656
class GoogleMailer extends Mailer
639657
{
658+
// ...
659+
640660
protected function configureOptions(OptionsResolver $resolver)
641661
{
642662
parent::configureOptions($resolver);
@@ -671,10 +691,10 @@ can change your code to do the configuration only once per class::
671691

672692
public function __construct(array $options = array())
673693
{
674-
// Are we a Mailer, a GoogleMailer, ... ?
694+
// What type of Mailer is this, a Mailer, a GoogleMailer, ... ?
675695
$class = get_class($this);
676696

677-
// Did we call configureOptions() before for this class?
697+
// Was configureOptions() executed before for this class?
678698
if (!isset(self::$resolversByClass[$class])) {
679699
self::$resolversByClass[$class] = new OptionsResolver();
680700
$this->configureOptions(self::$resolversByClass[$class]);
@@ -693,14 +713,14 @@ Now the :class:`Symfony\\Component\\OptionsResolver\\OptionsResolver` instance
693713
will be created once per class and reused from that on. Be aware that this may
694714
lead to memory leaks in long-running applications, if the default options contain
695715
references to objects or object graphs. If that's the case for you, implement a
696-
method ``clearDefaultOptions()`` and call it periodically::
716+
method ``clearOptionsConfig()`` and call it periodically::
697717

698718
// ...
699719
class Mailer
700720
{
701721
private static $resolversByClass = array();
702722

703-
public static function clearDefaultOptions()
723+
public static function clearOptionsConfig()
704724
{
705725
self::$resolversByClass = array();
706726
}
@@ -713,3 +733,5 @@ options in your code.
713733

714734
.. _Packagist: https://packagist.org/packages/symfony/options-resolver
715735
.. _Form component: http://symfony.com/doc/current/components/form/introduction.html
736+
.. _CHANGELOG: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/OptionsResolver/CHANGELOG.md#260
737+
.. _`read the Symfony 2.5 documentation`: http://symfony.com/doc/2.5/components/options_resolver.html

0 commit comments

Comments
 (0)