Events, Events & Events!

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Hi friends! Ok: so you already know how to use Symfony... maybe you... use it every day. Heck, I love it so much, I've been known to use it on vacation! And now, you're ready to go deeper - to find out how Symfony really works under-the-hood. If this is you, welcome! We're in for a wild ride.

In this first deep dive tutorial, we're going to the heart of what happens during the request-response process in Symfony. It all centers around a class called HttpKernel, which is an incredible class. This one class is used as the heart of Symfony and Drupal... as well as a bunch of other projects, for example, phpBB - the famous forum system.

So how can one class be the heart of technologies that are seemingly so different? That's what we're going to find out.

Project Setup

As always, if you truly want to impress your friends with your deep knowledge of Symfony, download the course code and code along with me. After you unzip the file, you'll find a start/ directory with the same code that you see here. Follow the README.md file for all the thrilling setup instructions.

The last step will be to leverage the Symfony binary to start a web server with symfony serve. I'm actually going to pass -d so it runs in the background as a daemon:

symfony serve -d

Now, spin back over to your browser and head to https://localhost:8000 to find: The SpaceBar. Some of you might recognize this from our Symfony 4 tutorials. Well, I've upgraded it to Symfony 5 and it will be our perfect guinea pig for diving deep into Symfony.

Request -> Controller -> Response. But what else?

Ok: we know that everything starts with a request: a request comes into our server, it's handled by our application, yadda, yadda, yadda, a response comes out... and profit! The goal of this tutorial is simple: find out what really happens in between.

For the homepage, let's find its controller: src/Controller/ArticleController.php. Here it is: homepage(), with the route above it.

The two things that we know happen between the start of the request and the end of the response, are that the route is matched and then something calls our controller... probably Fabien personally calls it... I don't know. And then our controller always, well usually, returns a response. That's what $this->render() returns.

What I want to know is: who executes the routing and who ultimately calls my controller? I want to see the code that does that!

Holder of Secrets: The Profiler Performance Tab

To start this journey, go back to your browser and, on the web debug toolbar on the bottom, right click on the milliseconds link and open it in a new tab to jump into the "Performance" section of the profiler.

This screen is awesome. It's meant to show you where your site might be slow, but its real superpower is that it can show you everything that's happening inside of Symfony. The trick is to change this "threshold" input box from 1 milliseconds down to 0... so that it doesn't hide anything.

Simply gorgeous. This is the request-response process. You can see - kind of in the middle here - is our controller: it took 36 milliseconds to execute. You can see the Twig templates being executed below it, and even little Doctrine queries happening along the way.

The biggest thing I want you to notice is that most of the other lines - both before and after the controller - contain the word Listener, or sometimes Subscriber, which is basically another word for "listener".

Because, at a high level, here's what happens inside Symfony: it boots, triggers some events, executes your controller, then dispatches some other events.

To get an even better view of these events, click... the Events tab! This shows all the events that were dispatched during this request. So, apparently there's an event called kernel.request: that was the first event dispatched. And here are all of the listeners - so all the "functions" - that were called when that event was triggered.

Then there's another event called kernel.controller... and many more. You can even see listeners for events that were not triggered during this request.

So... let's start messing with stuff! Next, let's create our own event listener and execute code before our controller is called.

Leave a comment!

  • 2020-06-28 Danijel Adrinek

    I tried setting up the project by readme file, but as soon as I try to run composer install, this error pops up in the terminal:

    composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev) from lock file
    Your requirements could not be resolved to an installable set of packages.

    Problem 1
    - Installation request for lorenzo/pinky 1.0.5 -> satisfiable by lorenzo/pinky[1.0.5].
    - lorenzo/pinky 1.0.5 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
    Problem 2
    - lorenzo/pinky 1.0.5 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
    - twig/inky-extra v2.12.5 requires lorenzo/pinky ^1.0.5 -> satisfiable by lorenzo/pinky[1.0.5].
    - Installation request for twig/inky-extra v2.12.5 -> satisfiable by twig/inky-extra[v2.12.5].

    To enable extensions, verify that they are enabled in your .ini files:
    - C:\xampp\php\php.ini
    You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

    EDIT: the problem has been fixed, I needed to enable xsl in php.ini file

  • 2020-06-10 weaverryan

    Hey Jay!

    Hmm. For simplicity, I committed the built Encore assets to the code download so that the site is effectively loading "static" CSS and JS files. I've just double-checked the starting code on my machine, and it *is* working. So, some questions :).

    A) What web server are you using? The symfony binary like we are? Or something else?
    B) If you try to load one of the CSS files directly - https://127.0.0.1:8000/build/app.css - what do you see? I'm guessing this fails, but what is the error wording exactly?

    Sorry about the troubles - but I'm sure it's something minor :).

    Cheers!

  • 2020-06-10 Jay

    The starting code in this section, for some reason, the styles aren't loading.

  • 2020-04-01 weaverryan

    Hey Justin!

    Yea, I totally borked this in the mailer tutorial when I originally did this. It's not a huge deal... but it definitely did *not* work as I originally intended. We're going to update the starting code in this tutorial (probably to use your parameters.uploads_base_url version) so that it works smoothly here.

    Thanks for the post!

    Cheers!

  • 2020-03-27 Justin

    The line SITE_BASE_URL=$SITE_BASE_SCHEME://$SITE_BASE_HOST in .env is broken. If I override either SITE_BASE_HOST or SITE_BASE_SCHEME in .env.local, SITE_BASE_URL ends up with the values from .env without taking the overrides. .env.local hasn't been parsed at the time .env is, so it sees the default values from .env. When .env.local is parsed, it's too late, SITE_BASE_URL has already been defined. To fix the images, you can copy the SITE_BASE_URL line to .env.local below the overridden SITE_BASE_HOST and/or SITE_BASE_SCHEME without changing it and the images should start working. Alternatively, you could change the definition of parameters.uploads_base_url to '%env(SITE_BASE_SCHEME)%://%env(SITE_BASE_HOST)%/uploads' in services.yaml and remove SITE_BASE_URL all together.