1
- Compiling the Container
1
+ Compiling the Container
2
2
=======================
3
3
4
4
The service container can be compiled for various reasons. These reasons
@@ -24,16 +24,19 @@ Creating a Compiler Pass
24
24
25
25
You can also create and register your own compiler passes with the container.
26
26
To create a compiler pass it needs to implements the :class: `Symfony\\ Component\\ DependencyInjection\\ Compiler\\ CompilerPassInterface `
27
- interface. The compiler gives you an opportunity to manipulate the service
27
+ interface. The compiler pass gives you an opportunity to manipulate the service
28
28
definitions that have been compiled. This can be very powerful, but is not
29
29
something needed in everyday use.
30
30
31
31
The compiler pass must have the ``process `` method which is passed the container
32
32
being compiled::
33
33
34
- public function process(ContainerBuilder $container)
34
+ class CustomCompilerPass
35
35
{
36
- //--
36
+ public function process(ContainerBuilder $container)
37
+ {
38
+ //--
39
+ }
37
40
}
38
41
39
42
The container's parameters and definitions can be manipulated using the
@@ -42,6 +45,43 @@ One common thing to do in a compiler pass is to search for all services that
42
45
have a certain tag in order to process them in some way or dynamically plug
43
46
each into some other service.
44
47
48
+ Registering a Compiler Pass
49
+ ---------------------------
50
+
51
+ You need to register your custom pass with the container. Tts process method
52
+ will then be called when the container is compiled::
53
+
54
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
55
+
56
+ $container = new ContainerBuilder();
57
+ $container->addCompilerPass(new CustomCompilerPass);
58
+
59
+ Controlling the Pass Ordering
60
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
+
62
+ The default compiler passes are grouped into optimization passes and removal
63
+ passes. The optimization passes run first and include tasks such as resolving
64
+ references within the definitions. The removal passes perform tasks such as removing
65
+ private aliases and unused services. You can choose where in the order any custom
66
+ passes you add are run. By default they will be run before the optimization passes.
67
+
68
+ You can use the following constants as the second argument when registering
69
+ a pass with the container to control where it goes in the order:
70
+
71
+ * ``PassConfig::TYPE_BEFORE_OPTIMIZATION ``
72
+ * ``PassConfig::TYPE_OPTIMIZE ``
73
+ * ``PassConfig::TYPE_BEFORE_REMOVING ``
74
+ * ``PassConfig::TYPE_REMOVE ``
75
+ * ``PassConfig::TYPE_AFTER_REMOVING ``
76
+
77
+ For example, to run your custom pass after the default removal passes have been run::
78
+
79
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
80
+
81
+ $container = new ContainerBuilder();
82
+ $container->addCompilerPass(new CustomCompilerPass, PassConfig::TYPE_AFTER_REMOVING);
83
+
84
+
45
85
Managing Configuration with Extensions
46
86
--------------------------------------
47
87
@@ -69,3 +109,83 @@ but are processed when the container's ``compile`` method is called.
69
109
You should instead use a compiler pass which works with the full container
70
110
after the extensions have been processed.
71
111
112
+ Dumping the Configuration for Performance
113
+ -----------------------------------------
114
+
115
+ Using configuration files to manage the service container can be much easier
116
+ to understand than using PHP once there are a lot of services. This ease comes
117
+ at a price though when it comes to performance as the config files need to be
118
+ parsed and the PHP configuration built from them. The compilation process makes
119
+ the container more efficient but it takes time to run. You can have the best of both
120
+ worlds though by using configuration files and then dumping and caching the resulting
121
+ configuration. The ``PhpDumper `` makes dumping the compiled container easy::
122
+
123
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
124
+ use Symfony\Component\Config\FileLocator;
125
+ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
126
+ use Symfony\Component\DependencyInjection\Dumper\PhpDumper
127
+
128
+ $container = new ContainerBuilder();
129
+ $loader = new XmlFileLoader($container, new FileLocator(__DIR__));
130
+ $loader->load('services.xml');
131
+
132
+ $file = __DIR__ .'/cache/container.php';
133
+
134
+ if (file_exists($file)) {
135
+ require_once $file;
136
+ $container = new ProjectServiceContiner();
137
+ } else {
138
+ $container = new ContainerBuilder();
139
+ //--
140
+ $container->compile();
141
+
142
+ $dumper = new PhpDumper($container);
143
+ file_put_contents($file, $dumper->dump());
144
+ }
145
+
146
+ ``ProjectServiceContiner `` is the default name given to the dumped container
147
+ class, you can change this though this with the ``class `` option when you dump
148
+ it::
149
+
150
+ // ...
151
+ $file = __DIR__ .'/cache/container.php';
152
+
153
+ if (file_exists($file)) {
154
+ require_once $file;
155
+ $container = new MyCachedContainer();
156
+ } else {
157
+ $container = new ContainerBuilder();
158
+ //--
159
+ $container->compile();
160
+
161
+ $dumper = new PhpDumper($container);
162
+ file_put_contents($file, $dumper->dump(array('class' => 'MyCachedContainer')));
163
+ }
164
+
165
+ You will now get the speed of the PHP configured container with the ease of using
166
+ configuration files. In the above example you will need to delete the cached
167
+ container file whenever you make any changes. Adding a check for a variable that
168
+ determines if you are in debug mode allows you to keep the speed of the cached
169
+ container in production but getting an up to date configuration whilst developing
170
+ your application::
171
+
172
+ // ...
173
+
174
+ // set $isDebug based on something in your project
175
+
176
+ $file = __DIR__ .'/cache/container.php';
177
+
178
+ if (!$isDebug && file_exists($file)) {
179
+ require_once $file;
180
+ $container = new MyCachedContainer();
181
+ } else {
182
+ $container = new ContainerBuilder();
183
+ //--
184
+ $container->compile();
185
+
186
+ if(!$isDebug)
187
+ $dumper = new PhpDumper($container);
188
+ file_put_contents($file, $dumper->dump(array('class' => 'MyCachedContainer')));
189
+ }
190
+ }
191
+
0 commit comments