Route, Controllers & Responses!

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.

The page we're looking at right now... which is super fun... and even changes colors... is just here to say "Hello!". Symfony is rendering this because, in reality, our app doesn't have any real pages yet. Let's change that.

Route + Controller = Page

Every web framework... in any language... has the same main job: to give you a route & controller system: a 2-step system to build pages. A route defines the URL of the page and the controller is where we write PHP code to build that page, like the HTML or JSON.

Open up config/routes.yaml:

#index:
# path: /
# controller: App\Controller\DefaultController::index

Hey! We already have an example! Uncomment that. If you're not familiar with YAML, it's super friendly: it's a key-value config format that's separated by colons. Indentation is also important.

This creates a single route whose URL is /. The controller points to a function that will build this page... really, it points to a method on a class. Overall, this route says:

when the user goes to the homepage, please execute the index method on the DefaultController class.

Oh, and you can ignore that index key at the top of the YAML: that's an internal name for the route... and it's not important yet.

Our App

The project we're building is called "Cauldron Overflow". We originally wanted to create a site where developers could ask questions and other developers answered them but... someone beat us to it... by... like 10 years. So like all impressive startups, we're pivoting! We've noticed a lot of wizards accidentally blowing themselves up... or conjuring fire-breathing dragons when they meant to create a small fire for roasting marshmallows. And so... Cauldron Overflow is here to become the place for witches and wizards to ask and answer questions about magical misadventures.

Creating a Controller

On the homepage, we will eventually list some of the most recent questions. So let's change the controller class to QuestionController and the method to homepage.

index:
path: /
controller: App\Controller\QuestionController::homepage

Ok, route done: it defines the URL and points to the controller that will build the page. Now... we need to create that controller! Inside the src/ directory, there's already a Controller/ directory... but it's empty. I'll right click on this and select "New PHP class". Call it QuestionController.

Namespaces & the src/ Directory

Ooh, check this out. It pre-filled the namespace! That's awesome! This is thanks to the Composer PhpStorm configuration we did in the last chapter.

Here's the deal: every class we create in the src/ directory will need a namespace. And... for reasons that aren't super important, the namespace must be App\ followed whatever directory the file lives in. Because we're creating this file in the Controller/ directory, its namespace must be App\Controller. PhpStorm will pre-fill this every time.

... lines 1 - 2
namespace App\Controller;
... lines 4 - 6
class QuestionController
{
... lines 9 - 12
}

Perfect! Now, because in routes.yaml we decided to call the method homepage, create that here: public function homepage().

... lines 1 - 2
namespace App\Controller;
... lines 4 - 6
class QuestionController
{
public function homepage()
{
... line 11
}
}

Controllers Return a Response

And.. congratulations! You are inside of a controller function, which is also sometimes called an "action"... to confuse things. Our job here is simple: to build the page. We can write any code we need to do that - like to make database queries, cache things, perform API calls, mine cryptocurrencies... whatever. The only rule is that a controller function must return a Symfony Response object.

Say return new Response(). PhpStorm tries to auto-complete this... but there are multiple Response classes in our app. The one we want is from Symfony\Component\HttpFoundation. HttpFoundation is one of the most important parts - or "components" - in Symfony. Hit tab to auto-complete it.

But stop! Did you see that? Because we let PhpStorm auto-complete that class for us, it wrote Response, but it also added the use statement for this class at the top of the file! That is one of the best features of PhpStorm and I'm going to use it a lot. You will constantly see me type a class and allow PhpStorm to auto-complete it so that it adds the use statement to the top of the file for me.

Inside new Response(), add some text:

What a bewitching controller we have conjured!

... lines 1 - 2
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class QuestionController
{
public function homepage()
{
return new Response('What a bewitching controller we have conjured!');
}
}

And... done! We just created our first page! Let's try it! When we go to the homepage, it should execute our controller function... which returns the message.

Find your browser. We're already on the homepage... so just refresh. Say hello to our very first page. I know, it's not much to look at yet, but we've already covered the most foundational part of Symfony: the route and controller system.

Next, let's make our route fancier by using something called annotations. We'll also create a second page with a route that matches a wildcard path.

Leave a comment!

  • 2020-06-24 Victor Bocharsky

    Hey Maria,

    OK, could you tell me what URL you're on when seeing that 404 error? Actually, this error means that such route does not exist in your Symfony application. You can check what routes are registered with the next command:

    $ bin/console debug:router

    This should help to know what URL you have. If it does not help to you - please, show the output of this command to me and tell me what exactly URL you're going to open in your browser that gives you 404 error.

    Cheers!

  • 2020-06-24 Maria

    Hey,

    I have this error #page not found..
    I did everything in the script and everthing ging well, i have also the question page, but whene i wrote in PHPstorm $slug part, it says page not found
    on the symfony local server.

  • 2020-06-22 Victor Bocharsky

    Hey Maria,

    I would be glad to help you! Could you tell me a bit more? What do you do exactly? Did you run any commands? Do you see any errors?

    Cheers!

  • 2020-06-18 Maria

    My page it does'nt found. can you help me?

  • 2020-06-16 weaverryan

    > Ps: Sorry for the double entry

    No problem - I'm answering of here ;) https://symfonycasts.com/sc...

  • 2020-06-16 Samuel Sekegor

    My php storm is not bringing out the full prediction when I'm typing
    Return new response...

    Hence its unable to auto complete the use symfony\component\httpfoundation\response;

    Is the problem with the php storm or my installations, I'm using windows and I also noticed that your initial command (symfony new cauldron_overflow) is not working.

    Ps: Sorry for the double entry

  • 2020-04-14 weaverryan

    Hey Rodrigo Valentim!

    Do you mean that we forgot to tell you to run composer install to install your dependencies? If so, you're 100% correct that this is needed. In the first video of this course, we walk through how you can create a totally new project. When you do that, the symfony executable runs composer install for you. So, it should already be done. However, if you decided to NOT do that, and download the "start" code from this course, then you *would* need to follow the README.md file in that directory, which includes directions to run composer install. Unfortunately, I don't know if there's a better way for us to "highlight" that you need to do this... as we're expecting that you created a totally new project with us in the first video :). If you have any suggestions on what would have made it more clear for you, let us know!

    Cheers!

  • 2020-04-14 Rodrigo Valentim

    The video forgot to say that needs to update the vendor directory.

  • 2020-03-16 Victor Bocharsky

    Hey Andrew,

    We just want to give our users information little by little. We will use Symfony console later along with MakerBundle. We don't have PHPDoc annotations because in this video we explain how to create routes in Yaml config file, see "config/routes.yaml". We will use annotation routes later in this course as well, just don't want to complicate things too much in the beginning.

    Cheers!

  • 2020-03-15 Andrew Ryasantsev

    But why you have not used console? Where is phpdoc annotations?

  • 2020-03-10 Thomas

    OK, but it sounds a little strange to me. If the controller class hosts only one method, you must have tons a controller classes. When I look at some projects I did, I think it's a lot of work (-_-).

    Thanks for the vote :-)

  • 2020-03-09 weaverryan

    Hey Thomas!

    > I'm curious of this best practice, do you have a link?

    It's not an official best-practice, just one that you see some people in the Symfony community doing. For example, Kevin Dunglas likes it a lot, so yo use it in API Platform examples (and they use it internally).

    > But, I'd like to see HA or Clean Architecture with Symfony too!

    I'll add a couple of votes for this tutorial internally :).

    Cheers!

  • 2020-03-09 weaverryan

    Hey Abelardo León González!

    > I think we should create a __invoke method inside a controller since it's a best practice a controller hosts a unique method.

    I think this is a fine way to do things :). I personally don't do it - but I have no problem if people do. I prefer organizing my controllers approximately around a feature or an entity, and then having several methods inside.

    > Another question: will you create this project by using Hexagonal Architecture from beginning...or it will be released inside another course?

    That will be another course. For these beginner courses, we need to be pragmatic :).

    Cheers!

  • 2020-03-09 Thomas

    I'm curious of this best practice, do you have a link?

    In theory, Hexagonal Architecture is framework agnostic. But, I'd like to see HA or Clean Architecture with Symfony too!

  • 2020-03-07 Abelardo León González

    I think we should create a __invoke method inside a controller since it's a best practice a controller hosts a unique method.

    Another question: will you create this project by using Hexagonal Architecture from beginning...or it will be released inside another course?

    Cheers