@@ -19,7 +19,7 @@ Want a logging system? No problem:
19
19
$ composer require logger
20
20
21
21
This installs and configures (via a recipe) the powerful `Monolog `_ library. To
22
- use the logger in a controller, add a new argument type-hinted with ``LoggerInterface ``:
22
+ use the logger in a controller, add a new argument type-hinted with ``LoggerInterface ``::
23
23
24
24
use Psr\Log\LoggerInterface;
25
25
// ...
@@ -71,7 +71,7 @@ Creating Services
71
71
72
72
To keep your code organized, you can even create your own services! Suppose you
73
73
want to generate a random greeting (e.g. "Hello", "Yo", etc). Instead of putting
74
- this code directly in your controller, create a new class:
74
+ this code directly in your controller, create a new class::
75
75
76
76
// src/GreetingGenerator.php
77
77
namespace App;
@@ -129,11 +129,189 @@ difference is that it's done in the constructor:
129
129
}
130
130
}
131
131
132
- Yes! This works too: no configuration, no time wasted.
132
+ Yes! This works too: no configuration, no time wasted. Keep coding!
133
133
134
- Event Subscriber
135
- ----------------
134
+ Twig Extension & Autoconfiguration
135
+ ----------------------------------
136
136
137
+ Thanks to Symfony's service handling, you can *extend * Symfony in many ways, like
138
+ by creating an event subscriber or or a security voter for complex authorization
139
+ rules. Let's add a new filter to Twig called ``greet ``. How? Just create a class
140
+ that extends ``AbstractExtension ``::
137
141
142
+ // src/Twig/GreetExtension.php
143
+ namespace App\Twig;
144
+
145
+ use App\GreetingGenerator;
146
+ use Twig\Extension\AbstractExtension;
147
+ use Twig\TwigFilter;
148
+
149
+ class GreetExtension extends AbstractExtension
150
+ {
151
+ private $greetingGenerator;
152
+
153
+ public function __construct(GreetingGenerator $greetingGenerator)
154
+ {
155
+ $this->greetingGenerator = $greetingGenerator;
156
+ }
157
+
158
+ public function getFilters()
159
+ {
160
+ return [
161
+ new TwigFilter('greet', [$this, 'greetUser']),
162
+ ];
163
+ }
164
+
165
+ public function greetUser($name)
166
+ {
167
+ $greeting = $this->greetingGenerator->getRandomGreeting();
168
+
169
+ return "$greeting $name!";
170
+ }
171
+ }
172
+
173
+ After creating just *one * file, you can use this immediately:
174
+
175
+ .. code-block :: twig
176
+
177
+ {# Will print something like "Hey Symfony!" #}
178
+ <h1>{{ name|greet }}</h1>
179
+
180
+ How does this work? Symfony notices that your class extends ``AbstractExtension ``
181
+ and so *automatically * registers it as a Twig extension. This is called autoconfiguration,
182
+ and it works for *many * many things. Just create a class and then extend a base class
183
+ (or implement an interface). Symfony takes care of the rest.
184
+
185
+ Blazing Speed: The Cached Container
186
+ -----------------------------------
187
+
188
+ After seeing how much Symfony handles automatically, you might be wondering: "Doesn't
189
+ this hurt performance?" Actually, no! Symfony is blazing fast.
190
+
191
+ How is that possible? The service system is managed by a very important object called
192
+ the "container". Most frameworks have a container, but Symfony's is unique because
193
+ it's *cached *. When you loaded your first page, all of the service information was
194
+ compiled and saved. This means that the autowiring and autoconfiguration features
195
+ add *no * overhead! It also means that you get *great * errors: Symfony inspects and
196
+ validates *everything * when the container is built.
197
+
198
+ Now you might be wondering what happens when you update a file and the cache needs
199
+ to rebuild? I like you're thinking! It's smart enough to rebuild on the next page
200
+ load. But that's really the topic of the next section.
201
+
202
+ Development Versus Production: Environments
203
+ -------------------------------------------
204
+
205
+ One of a framework's main jobs is to make debugging easy! And our app is *full * of
206
+ great tools for this: the web debug toolbar displays at the bottom of the page, errors
207
+ are big, beautiful & explicit, and any configuration cache is automatically rebuilt
208
+ whenever needed.
209
+
210
+ But what about when you deploy to production? We will need to hide those tool and
211
+ optimize for speed!
212
+
213
+ This is solved by Symfony's *environment * system and there are three: ``dev ``, ``prod ``
214
+ and ``test ``. Based on the environment, Symfony loads different files in the ``config/ ``
215
+ directory:
216
+
217
+ .. code-block :: text
218
+
219
+ config/
220
+ ├─ services.yaml
221
+ ├─ ...
222
+ └─ packages/
223
+ ├─ framework.yaml
224
+ ├─ ...
225
+ ├─ **dev/**
226
+ ├─ monolog.yaml
227
+ └─ ...
228
+ ├─ **prod/**
229
+ └─ monolog.yaml
230
+ └─ **test/**
231
+ ├─ framework.yaml
232
+ └─ ...
233
+ └─ routes/
234
+ ├─ annotations.yaml
235
+ └─ **dev/**
236
+ ├─ twig.yaml
237
+ └─ web_profiler.yaml
238
+
239
+ This is a *powerful * idea: by changing one piece of configuration (the environment),
240
+ your app is transformed from a debugging-friendly experience to one that's optimized
241
+ for speed.
242
+
243
+ Oh, how do you change the environment? Change the ``APP_ENV `` environment variable
244
+ from ``dev `` to ``prod ``:
245
+
246
+ .. code-block :: diff
247
+
248
+ # .env
249
+ - APP_ENV=dev
250
+ + APP_ENV=prod
251
+
252
+ But I want to talk more about environment variables next. Change the value back
253
+ to ``dev ``: debugging tools are great when you're working locally.
254
+
255
+ Environment Variables
256
+ ---------------------
257
+
258
+ Every app contains configuration that's different on each server - like database
259
+ connection information or passwords. How should these be stored? In files? Or some
260
+ other way?
261
+
262
+ Symfony follows the industry best practice by storing server-based configuration
263
+ as *environment * variables. This means that Symfony works *perfectly * with
264
+ Platform as a Service (PaaS) deployment systems as well as Docker.
265
+
266
+ But setting environment variables while developing can be a pain. That's why your
267
+ app automatically loads a ``.env `` file, if the ``APP_ENV `` environment variable
268
+ isn't set in the environment. The keys in this file then become environment variables
269
+ are and read by your app:
270
+
271
+ .. code-block :: bash
272
+
273
+ # .env
274
+ # ##> symfony/framework-bundle ###
275
+ APP_ENV=dev
276
+ APP_SECRET=cc86c7ca937636d5ddf1b754beb22a10
277
+ # ##< symfony/framework-bundle ###
278
+
279
+ At first, the file doesn't contain much. But as your app grows, you'll add more
280
+ configuration as you need it. But, actually, it gets much more interesting! Suppose
281
+ your app needs database ORM. Let's install the Doctrine ORM:
282
+
283
+ .. code-block :: terminal
284
+
285
+ $ composer require doctrine
286
+
287
+ Thanks to a new recipe installed by Flex, look at the ``.env `` file again:
288
+
289
+ .. code-block :: diff
290
+
291
+ ###> symfony/framework-bundle ###
292
+ APP_ENV=dev
293
+ APP_SECRET=cc86c7ca937636d5ddf1b754beb22a10
294
+ ###< symfony/framework-bundle ###
295
+
296
+ + ###> doctrine/doctrine-bundle ###
297
+ + # ...
298
+ + DATABASE_URL=mysql://db_user:[email protected] :3306/db_name
299
+ + ###< doctrine/doctrine-bundle ###
300
+
301
+ The new ``DATBASE_URL `` environment variable was added *automatically * and is already
302
+ referenced by the new ``doctrine.yaml `` configuration file. By combining environment
303
+ variables and Flex, you're using industry best practices without any extra effort.
304
+
305
+ Keep Going!
306
+ -----------
307
+
308
+ Call me crazy, but after reading this part, you should be comfortable with the most
309
+ *important * parts of Symfony. Everything in Symfony is designed to get out of your
310
+ way so you can keep coding and adding features, all with the speed and quality you
311
+ demand.
312
+
313
+ That's all for the quick tour. From authentication, to forms, to caching, there is
314
+ so much more to discover. Ready to dig into these topics now? Look no further - go
315
+ to the official :doc: `/index ` and pick any guide you want.
138
316
139
317
.. _`Monolog` : https://github.com/Seldaek/monolog
0 commit comments