gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Hey friends! Welcome back to Episode 2 of our Symfony 6 tutorial series. This is the one where we seriously level-up and unlock our potential to do anything we want. That's because, in this course, we're diving into the fundamentals behind everything in Symfony. We're talking about services, bundles, configuration, environments, environment variables - the stuff that truly makes Symfony tick. We're gonna throw open Symfony's hood and find out what's inside.
To get the most fundamentals out of this fundamentals tutorial, I warmly invite you to cozy up to a fire, download the course code from this page and code along with me. It'll be fun! After you unzip the file, you'll find a start/
directory with the same code that you see here. Follow our hand-crafted, locally-sourced README.md
file for all of the setup instructions. The last step will be to open a terminal, move into the project and run
symfony serve -d
to start a local web server at https://127.0.0.1:8000
. I'll cheat and click that link to see our site. It is... Mixed Vinyl! Our new startup where users can build their own custom "mixtape" - I'm thinking MMMBop followed by some Spice Girls - except that we deliver it straight to your door on a freshly pressed vinyl record. We even throw in that musty old record collection smell for free!
In the previous tutorial, we talked briefly about how everything in Symfony is actually done by a service. And that the word "service" is a fancy term for a simple concept: a service is an object that does work.
For example, in src/Controller/SongController.php
, we leveraged Symfony's Logger service to log a message:
... lines 1 - 4 | |
use Psr\Log\LoggerInterface; | |
... lines 6 - 10 | |
class SongController extends AbstractController | |
{ | |
... line 13 | |
public function getSong(int $id, LoggerInterface $logger): Response | |
{ | |
... lines 16 - 22 | |
$logger->info('Returning API response for song {song}', [ | |
'song' => $id, | |
]); | |
... lines 26 - 27 | |
} | |
} |
And, though we don't have the code in VinylController
anymore, we briefly used the Twig service to directly render a Twig template:
... lines 1 - 9 | |
class VinylController extends AbstractController | |
{ | |
... line 12 | |
public function homepage(): Response | |
{ | |
... lines 15 - 23 | |
return $this->render('vinyl/homepage.html.twig', [ | |
... lines 25 - 26 | |
]); | |
} | |
... lines 29 - 38 | |
} |
So a service is just an object that does work... and every bit of work that's done in Symfony is done by a service. Heck, even the core code that figures which route matches the current URL is a service, called the "router" service.
So the next question is: where do these services come from? The answer to that is mordor. I mean bundles... services come from bundles.
Open up config/bundles.php
:
return [ | |
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], | |
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], | |
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], | |
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], | |
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], | |
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], | |
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], | |
Symfony\UX\Turbo\TurboBundle::class => ['all' => true], | |
]; |
This isn't a file that you need to look at or worry about much, but this is where your bundles are activated.
Very simply: bundles are Symfony plugins. They're just PHP code... but they hook into Symfony. And thanks to the recipe system, when we install a new bundle, that bundle is automatically added to this file, which is how we already have 8 bundles here. When we started our project, we only had 1!
So a bundle is a Symfony plugin. And bundles can give us several things... though they largely exist for one reason: to give us services. For example, this TwigBundle up here gives us the Twig service. If we removed this line, the Twig service would no longer exist and our application would explode... since we are rendering templates. This render()
line would no longer work. And MonologBundle is what gives us the Logger service that we're using in SongController
.
So by adding more bundles into our application, we're getting more services, and services are tools! Need more services? Install more bundles! It's like Neo in the best, I mean first Matrix movie.
Next... let's teach our app some Kung fu by installing a new bundle that gives us a new service to solve a new problem.
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"knplabs/knp-time-bundle": "^1.18", // v1.19.0
"symfony/asset": "6.1.*", // v6.1.0-RC1
"symfony/console": "6.1.*", // v6.1.0-RC1
"symfony/dotenv": "6.1.*", // v6.1.0-RC1
"symfony/flex": "^2", // v2.1.8
"symfony/framework-bundle": "6.1.*", // v6.1.0-RC1
"symfony/http-client": "6.1.*", // v6.1.0-RC1
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/runtime": "6.1.*", // v6.1.0-RC1
"symfony/twig-bundle": "6.1.*", // v6.1.0-RC1
"symfony/ux-turbo": "^2.0", // v2.1.1
"symfony/webpack-encore-bundle": "^1.13", // v1.14.1
"symfony/yaml": "6.1.*", // v6.1.0-RC1
"twig/extra-bundle": "^2.12|^3.0", // v3.4.0
"twig/twig": "^2.12|^3.0" // v3.4.0
},
"require-dev": {
"symfony/debug-bundle": "6.1.*", // v6.1.0-RC1
"symfony/maker-bundle": "^1.41", // v1.42.0
"symfony/stopwatch": "6.1.*", // v6.1.0-RC1
"symfony/web-profiler-bundle": "6.1.*" // v6.1.0-RC1
}
}