Skip to content

Commit c024ef2

Browse files
wouterjweaverryan
authored andcommitted
Added article about loaders
1 parent e50e2fa commit c024ef2

File tree

3 files changed

+183
-2
lines changed

3 files changed

+183
-2
lines changed

components/validator/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Validator
55
:maxdepth: 2
66

77
introduction
8+
resources

components/validator/introduction.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ What things you can configure will be documented in the following sections.
6969
Sections
7070
--------
7171

72-
* :doc:`/components/validator/loading_resources`
73-
* :doc:`/components/validator/defining_metadata`
72+
* :doc:`/components/validator/resources`
73+
* :doc:`/components/validator/metadata`
7474
* :doc:`/components/validator/validating_values`
7575

7676
.. _`JSR-303 Bean Validation specification`: http://jcp.org/en/jsr/detail?id=303

components/validator/resources.rst

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
.. index::
2+
single: Validator; Loading Resources
3+
4+
Loading Resources
5+
=================
6+
7+
The Validator uses metadata to validate a value. This metadata defines how a
8+
class, array or any other value should be validated. When validating a class,
9+
each class contains its own specific metadata. When validating another value,
10+
the metadata to passed to the validate methods.
11+
12+
Class metadata should be defined somewhere in a configuration file, or in the
13+
class itself. The ``Validator`` needs to be able to retrieve this metadata
14+
from the file or class. To do that, it uses a set of loaders.
15+
16+
.. seealso::
17+
18+
You'll learn how to define the metadata in :doc:`metadata`.
19+
20+
The StaticMethodLoader
21+
----------------------
22+
23+
The easiest loader is the
24+
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\StaticMethodLoader`.
25+
This loader will call a static method of the class in order to get the
26+
metadata for that class. The name of the method is configured using the
27+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMapping`
28+
method of the Validator builder::
29+
30+
use Symfony\Component\Validator\Validation;
31+
32+
$validator = Validation::createValidatorBuilder()
33+
->addMethodMapping('loadValidatorMetadata')
34+
->getValidator();
35+
36+
Now, the retrieved ``Validator`` tries to find the ``loadValidatorMetadata()``
37+
method of the validated class to load its metadata.
38+
39+
.. tip::
40+
41+
You can call this method multiple times to add multiple supported method
42+
names. You can also use
43+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMappings`
44+
to set an array of supported method names.
45+
46+
The FileLoaders
47+
---------------
48+
49+
The component also provides 2 file loaders, one to load Yaml files and one to
50+
load XML files. Use
51+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addYamlMapping` or
52+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMapping` to
53+
configure the locations of these files::
54+
55+
use Symfony\Component\Validator\Validation;
56+
57+
$validator = Validation::createValidatorBuilder()
58+
->addYamlMapping('config/validation.yml')
59+
->getValidator();
60+
61+
.. tip::
62+
63+
Just like with the method mappings, you can also use
64+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addYamlMappings` and
65+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMappings`
66+
to configure an array of file paths.
67+
68+
The AnnotationLoader
69+
--------------------
70+
71+
At last, the component provides an
72+
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader`.
73+
This loader will parse the annotations of a class. Annotations are placed in
74+
PHPdoc comments (`/** ... */`) and start with an ``@``. For instance::
75+
76+
// ...
77+
78+
/**
79+
* @Assert\NotBlank()
80+
*/
81+
protected $name;
82+
83+
To enable the annotation loader, call the
84+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping`
85+
method. It takes an optional annotation reader instance, which defaults to
86+
``Doctrine\Common\Annotations\AnnotationReader``::
87+
88+
use Symfony\Component\Validator\Validation;
89+
90+
$validator = Validation::createValidatorBuilder()
91+
->enableAnnotationMapping()
92+
->getValidator();
93+
94+
To disable the annotation loader after it was enabled, call
95+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAnnotationMapping`.
96+
97+
.. note::
98+
99+
In order to use the annotation loader, you should have installed the
100+
``doctrine/annotations`` and ``doctrine/cache`` packages of Packagist.
101+
102+
Using Multiple Loaders
103+
----------------------
104+
105+
The component provides a
106+
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderChain` class to
107+
chain multiple loaders. This means you can configure as many loaders as you
108+
want at the same time.
109+
110+
The ``ValidatorBuilder`` will already take care of this when you configure
111+
multiple mappings::
112+
113+
use Symfony\Component\Validator\Validation;
114+
115+
$validator = Validation::createValidatorBuilder()
116+
->enableAnnotationMapping()
117+
->addMethodMapping('loadValidatorMetadata')
118+
->addXmlMapping('config/validation.xml')
119+
->getValidator();
120+
121+
Caching
122+
-------
123+
124+
Using many loaders to load metadata from different places is very easy for the
125+
developer, but it can easily slow down your application since each file needs
126+
to be parsed, validated and converted to a
127+
:class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata` instance. To
128+
solve this problems, you can configure a cacher which will be used to cache
129+
the ``ClassMetadata`` after it was loaded.
130+
131+
The Validator component comes with a
132+
:class:`Symfony\\Component\\Validator\\Mapping\\Cache\\ApcCache`
133+
implementation. You can easily create other cachers by creating a class which
134+
implements :class:`Symfony\\Component\\Validator\\Mapping\\Cache\\CacheInterface`.
135+
136+
.. note::
137+
138+
The loader already use a singleton load mechanism. That means that they
139+
will only load and parse a file once and put that in a property, which
140+
will be used on the next time. However, the Validator still needs to
141+
merge all metadata of one class from every loader when it is requested.
142+
143+
To set a cacher, call the
144+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataCache` of
145+
the Validator builder::
146+
147+
use Symfony\Component\Validator\Validation;
148+
use Symfony\Component\Validator\Mapping\Cache\ApcCache;
149+
150+
$validator = Validation::createValidatorBuilder()
151+
// ... add loaders
152+
->setMetadataCache(new ApcCache('some_apc_prefix'));
153+
->getValidator();
154+
155+
Using a Custom MetadataFactory
156+
------------------------------
157+
158+
All loaders and the cacher are passed to an instance of
159+
:class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadataFactory`. This
160+
class is responsible for creating a ``ClassMetadata`` instance from all the
161+
configured resources.
162+
163+
You can also use a custom metadata factory implementation by creating a class
164+
which implements
165+
:class:`Symfony\\Component\\Validator\\MetadataFactoryInterface`. You can set
166+
this custom implementation using
167+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataFactory`::
168+
169+
use Acme\Validation\CustomMetadataFactory;
170+
use Symfony\Component\Validator\Validation;
171+
172+
$validator = Validation::createValidatorBuilder()
173+
->setMetadataFactory(new CustomMetadataFactory(...));
174+
->getValidator();
175+
176+
.. caution::
177+
178+
Since you are using a custom metadata factory, you can't configure loaders
179+
and cachers using the helper methods anymore. You now have to inject them
180+
into your custom metadata factory yourself.

0 commit comments

Comments
 (0)