gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Let's create our first page! Actually, this is the main job of a framework: to give you a route and controller system. A route is configuration that defines the URL for a page and a controller is a function that we write that actually builds the content for that page.
And right now... our app is really small! Instead of weighing down your project with every possible feature you could ever need - after all, we're not in zero-gravity yet - a Symfony app is basically just a small route-controller system. Later, we'll install more features when we need them, like a warp drive! Those always come in handy. Adding more features is actually going to be pretty awesome. More on that later.
Open your app's main routing file: config/routes.yaml
:
#index: | |
# path: / | |
# controller: App\Controller\DefaultController::index |
Hey! We already have an example! Uncomment that. Ignore the index
key for now: that's the internal name of the route, but it's not important yet.
This says that when someone goes to the homepage - /
- Symfony should execute an index()
method in a DefaultController
class. Change this to ArticleController
and the method to homepage
:
index: | |
path: / | |
controller: App\Controller\ArticleController::homepage |
And... yea! That's a route! Hi route! It defines the URL and tells Symfony what controller function to execute.
The controller class doesn't exist yet, so let's create it! Right-click on the Controller
directory and go to "New" or press Cmd
+N
on a Mac. Choose "PHP Class". And, yes! Remember that Composer setup we did in Preferences? Thanks to that, PhpStorm correctly guesses the namespace! The force is strong with this one... The namespace for every class in src/
should be App
plus whatever sub-directory it's in.
Name this ArticleController
:
namespace App\Controller; | |
... lines 4 - 6 | |
class ArticleController | |
{ | |
... lines 9 - 12 | |
} |
And inside, add public function homepage()
:
... lines 1 - 2 | |
namespace App\Controller; | |
... lines 4 - 6 | |
class ArticleController | |
{ | |
public function homepage() | |
{ | |
... line 11 | |
} | |
} |
This function is the controller... and it's our place to build the page. To be more confusing, it's also called an "action", or "ghob" to its Klingon friends.
Anyways, we can do whatever we want here: make database queries, API calls, take soil samples looking for organic materials or render a template. There's just one rule: a controller must return a Symfony Response
object.
So let's say: return new Response()
: we want the one from HttpFoundation
. Give it a calm message: OMG!
My first page already! WOOO!:
... lines 1 - 2 | |
namespace App\Controller; | |
use Symfony\Component\HttpFoundation\Response; | |
class ArticleController | |
{ | |
public function homepage() | |
{ | |
return new Response('OMG! My first page already! WOOO!'); | |
} | |
} |
Ahem. Oh, and check this out: when I let PhpStorm auto-complete the Response
class it added this use
statement to the top of the file automatically:
... lines 1 - 4 | |
use Symfony\Component\HttpFoundation\Response; | |
... lines 6 - 14 |
You'll see me do that a lot. Good job Storm!
Let's try the page! Find your browser. Oh, this "Welcome" page only shows if you don't have any routes configured. Refresh! Yes! This is our page. Our first of many.
That was pretty easy, but it can be easier! Instead of creating our routes in YAML, let's use a cool feature called annotations. This is an extra feature, so we need to install it. Find your open terminal and run:
composer require annotations
Interesting... this annotations
package actually installed sensio/framework-extra-bundle
. We're going to talk about how that works very soon.
Now, about these annotation routes. Comment-out the YAML route:
#index: | |
# path: / | |
# controller: App\Controller\ArticleController::homepage |
Then, in ArticleController
, above the controller method, add /**
, hit enter, clear this out, and say @Route()
. You can use either class - but make sure PhpStorm adds the use
statement on top. Then add "/"
:
... lines 1 - 4 | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
... lines 6 - 7 | |
class ArticleController | |
{ | |
/** | |
* @Route("/") | |
*/ | |
public function homepage() | |
{ | |
... line 15 | |
} | |
} |
Tip
When you auto-complete the @Route
annotation, be sure to choose the
one from Symfony\Component\Routing
- the one we chose is now deprecated.
Both work the same.
That's it! The route is defined right above the controller, which is why I love annotation routes: everything is in one place. But don't trust me, find your browser and refresh. It's a traaaap! I mean, it works!
Tip
What exactly are annotations? They're PHP comments that are read as configuration.
So what else can we do with routes? Create another public function called show()
. I want this page to eventually display a full article. Give it a route: @Route("/news/why-asteroids-taste-like-bacon")
:
... lines 1 - 4 | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
... lines 6 - 7 | |
class ArticleController | |
{ | |
... lines 10 - 17 | |
/** | |
* @Route("/news/why-asteroids-taste-like-bacon") | |
*/ | |
public function show() | |
{ | |
... line 23 | |
} | |
} |
Eventually, this is how we want our URLs to look. This is called a "slug", it's a URL version of the title. As usual, return a new Response('Future page to show one space article!')
:
... lines 1 - 4 | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
use Symfony\Component\HttpFoundation\Response; | |
class ArticleController | |
{ | |
... lines 10 - 17 | |
/** | |
* @Route("/news/why-asteroids-taste-like-bacon") | |
*/ | |
public function show() | |
{ | |
return new Response('Future page to show one space article!'); | |
} | |
} |
Perfect! Copy that URL and try it in your browser. It works... but this sucks! I don't want to build a route and controller for every single article that lives in the database. Nope, we need a route that can match /news/
anything. How? Use {slug}
:
... lines 1 - 7 | |
class ArticleController | |
{ | |
... lines 10 - 17 | |
/** | |
* @Route("/news/{slug}") | |
*/ | |
public function show($slug) | |
{ | |
... lines 23 - 26 | |
} | |
} |
This route now matches /news/
anything: that {slug}
is a wildcard. Oh, and the name slug
could be anything. But whatever you choose now becomes available as an argument to your "ghob", I mean your action.
So let's refactor our success message to say:
Future page to show the article
And then that slug:
... lines 1 - 7 | |
class ArticleController | |
{ | |
... lines 10 - 17 | |
/** | |
* @Route("/news/{slug}") | |
*/ | |
public function show($slug) | |
{ | |
return new Response(sprintf( | |
'Future page to show the article: "%s"', | |
$slug | |
)); | |
} | |
} |
Try it! Refresh the same URL. Yes! It matches the route and the slug prints! Change it to something else: /why-asteroids-taste-like-tacos
. So delicious! Go back to bacon... because... ya know... everyone knows that's what asteroids really taste like.
And... yes! We're 3 chapters in and you now know the first half of Symfony: the route & controller system. Sure, you can do fancier things with routes, like match regular expressions, HTTP methods or host names - but that will all be pretty easy for you now.
It's time to move on to something really important: it's time to learn about Symfony Flex and the recipe system. Yum!
Hey Nick S.
At first sight I think you are not running on PHP 7. The operator ??
was introduce in PHP 7. If that's not the case, check the first line of your file, probably you have something like this "<"??php (had to wrap it with double quotes so Disqus can render it)
Cheers!
Thanks for the reply MolloKhan!
Unfortunately (fortunately?) I am, I had to update it from 5.6 to 7.1.3 to run Composer. Also, I think your "cheers" being in code format means there's something there that I'm not seeing?
Also thank you for being here to help, and being so responsive to everyone. Looking forward to being part of this community. :)
> Also, I think your "cheers" being in code format means there's something there that I'm not seeing?
Yeah you are right! Disqus messed it up - I just fixed it
If you still have this problem. Could you show me your entire index.php file please?
> Also thank you for being here to help, and being so responsive to everyone. Looking forward to being part of this community. :)
You are welcom man :)
I can't get it to paste into code, so I'm linking a screenshot: https://imgur.com/a/07J6TBh
Does that help?
Thanks again!
Hmm, your file looks correct. It makes think that you are not running on PHP7 in your web server (You may have installed PHP7 only to the CLI). Check the phpinfo of your webserver to double check what I'm saying. If that's the case, then you now know what to do :)
Cheers!
Hi everyone! If you have Symfony version 4.3 to use the annotations you need to insert this in your BlogController:
use Symfony\Component\Routing\Annotation\Route;
They changed the directory, that's why so many of you are receiving error messages.
Tip: To easily configure a new controller you can use the terminal by writing
php bin/console make:controller
Hope it helped!
Hi guys , I am a new beginner on this course. And i already face some issues.
someone can help me with this please.
After adding
/**
* @Route("/")
*/
I have this path but !!!!!!!
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
the last word Route is crossing. And it says that Class Route is depreciated
thank you!
Hey Yao,
I see you noticed this comment: https://symfonycasts.com/sc... - great, and I suppose your problem is solved. So basically, "Symfony\Component\Routing\Annotation\Route" class is a new official way to add routes annotations instead of deprecated "Sensio\Bundle\FrameworkExtraBundle\Configuration\Route" one. But instead of providing a BC break, Symfony warn us first saying it will be removed in future releases so you have time to update your code.
Cheers!
Hi Victor,
Nice to read you. Yeah i finally fixed my issue by replacing "Sensio\Bundle\FrameworkExtraBundle\Configuration\Route" with "Symfony\Component\Routing\Annotation\Route" class which is really cool.
Thanks for your assistance.
Yay, glad you had got it working before even we replied you. And yeah, it was an easy fix ;)
Cheers!
Want to share my experience, SF 4.1.2 Deprecation Message:
User Deprecated: The "Sensio\Bundle\FrameworkExtraBundle\Configuration\Route" annotation is deprecated since version 5.2. Use "Symfony\Component\Routing\Annotation\Route" instead.
The solution is pretty obvious, choose the other Route Class :)
Hey Yao,
Hm, I personally started to get familiar with Symfony since 2.1, but mostly started developing apps since 2.3 IIRC :)
Cheers!
Is it normal that the debug pack just has 5 symfony plugins instead of 6 ? bc in the tutorial he said it comes with 6.
Hey yao!
Yep, that's totally ok :). When I recorded this tutorial, that package downloaded 6 things. But a few months ago, one of the packages was removed (nothing too important) and so now you only get 5.
Cheers!
Hey Kutay Deril
What you mean by only client and env? Did you download the course code or did you started the project by yourself?
Cheers!
Hello!
I have controller and 2 child classes,
pretty similar to Template design pattern.
public class MyController
{
/**
*
*@Route("/add-item", name="addItem")
*/
public function addItem(){
$this->common();
$this->specific();
}
public function common() { ...}
}
} //MyController
public class Child1 extends MyController
{
public function specific( ) {...};
} // Child1
public class Child2
{
public function specific() {...}
} // Child2
I want to build links from twig so child class Child1::addItem be called.
Is there some special annotation for that?
How can it be achieved?
Thanks!
Hey Avraham M.
I don't think that it's a good idea to use hierarchies like that on controllers. If you want to re-use some methods among controllers, then, you can create a base class to hold all that logic, or maybe use a treat, besides that, what a controller should only have are route actions
Cheers!
Hey MolloKhan
I try to avoid code repetition.
The simple option I have is to create 2 ( or more) actions in Controller,
so actions make common stuff and some specific stuff for each.
I thought about template design pattern..
Can you please be more detailed about the base class and the structure to organize it?
Thanks!
p.s.
I thought about custom actions inside MyController,
how is it?
public class MyController
{
/**
*@Route(/specific1, "specific1")
**/
public function specific1()
{
$this->addItem(array $specificParams);
}
public function addItem(array $specific1Params, string $specific1Function)
{
common();
$this->{$specific1Function}(specific1Params);
}
} // MyController
Ohh, I see. Then, what you can do is to create a base abstract class that all your controllers with inherit and add all of your common logic/methods on it.
Tip: A controller should not *own* too much logic (and even less if it's business logic), so if you find yourself adding a lot of code to a controller that's a good hint that you may need a service class.
Cheers!
Not sure where my last comment went - or how to get the "support" that is advertised in the subscription promotional...
In this video, things seems to work as advertised.. until we get to the second method
`
/**
return new Response("OMG my first page");
}
/**
return new Response("Content for the second page");
}
`
I'm using MAMP to serve up these pages.. I've got a virtual host pointing at http://spacebar
So
http://spacebar/
<b>Works</b>
http://spacebar/news/item
<b>Does not work (e.g., throws a 404 page not found</b>
<b>The full controller page looks like this</b>
`
<?php
namespace App\Controller;
use Symfony\Com``ponent\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ArticleController
{
/**
return new Response("OMG my first page");
}
/**
return new Response("Content for the second page");
}
}
`
Hey Thomas W.
I'm sorry for the late reply. For some reason our software lost track of messages for a couple of days but it's back on business again!
As Vladimir said in the other comment. It seems like a problem with your web server. Probably this guide may help you out configuring it right https://symfony.com/doc/cur...
But, I recommend using Symfony's built-in webserver, it's just easier and faster to use when working locally
Cheers!
First annotated thing worked...
Second... getting page not found...
(I shorted the URL to /news for brevity)
` /**
return new Response('future page');
}
`
Hey Thomas W.
Looks like you webserver doesn't pass you request to public/index.php
. First page works because server pass /
to index.php by default. If you are using apache behind the MAMP, than you should try to install symfony/apache-pack
and it should fix it.
Cheers!
If anybody is having a 404 error from apache here's what i did to solve it:
composer require symfony/apache-pack.
manually create your .htaccess file and fill it with this:
https://github.com/symfony/...
And it should work just fine.
Hey Saul Solé
Thanks for sharing it :)
If you want to know more about configuring Apache for a Symfony app you can read this guide: https://symfony.com/doc/current/setup/web_server_configuration.html
You may have to add the DirectoryIndex index.php
rule if your homepage never ends loading
Cheers!
How to validate url in the route. Can you please help me in that regards And can provide me the tutorial link on
Sure, you can do fancier things with routes, like match regular expressions, HTTP methods or host names - but that will all be pretty easy for you now.
Thanks
Hey Sourodipta,
I'd recommend you to take a look at docs about this: https://symfony.com/doc/cur... . In particular:
> like match regular expressions
https://symfony.com/doc/cur...
> HTTP methods
https://symfony.com/doc/cur...
> host names
https://symfony.com/doc/cur...
We do cover some of it in further screencasts, but I'd not recommend you to jump to them directly and skip chapters to avoid losing context. Just go further in this track: https://symfonycasts.com/tr... . Otherwise, you can use our search for find related articles.
I hope this helps!
Cheers!
Hmm, I don't! I just checked it out. It looks crazy! Really beautiful! I imagine it takes some getting used to!
I am getting "An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "workspace_show" as such route does not exist.").". When I run php bin/console debug:router, I can find the route name there. Where is than the problem coming from?
Hey Teodora Moldovan
That's odd, it makes me think that you may have restricted that route to work with only specific request methods (such as POST). Let me see the output of your php bin/console debug:router
BTW, try clearing the cache, I mean, just in case :)
Cheers!
Thank you! I tried clearing the cache before and it didn’t work. However, it worked after I closed and reopened PhpStorm.
Really? PHPStorm? that's even weirder! haha, but I'm glad to hear that your problem is fixed now
Cheers!
Hi!! I have a question, when I want the autocomplete for my code php don't appear, but in my first test appear, I have the package php-autocomplete, but in this test don't work, what can I do?
PD1: Sorry for my english.
PD2: I'm using Atom instead phpstorm
Hey Mau España!
If you're serious about getting auto-completion, use PHPStorm. It's that simple. You can get some really nice things from Atom (I use it as my editor for everything *except* developing), but PHPStorm is many levels better. You will get PHP autocompletion and Symfony-specific auto-completion. You can out our phpstorm tutorial to learn more about this: https://symfonycasts.com/sc...
Cheers!
Hello! When I use Route, i get error 404 Not Found.
ArticleController.php
`
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ArticleController
{
/**
* @Route("/")
*/
public function homepage()
{
return new Response("My first page done! v2");
}
/**
* @Route("/news/why")
*/
public function show(){
return new Response("Future page to show one spse");
}
}
`
Homepage is working. But "/news/why" page not working. I get error 404.
Help to fix it, please.
Hey Dmitrii,
First of all, try to clear the cache! Especially, if you're running your website in prod mode. Then, here's the trick to make sure if your route exist or no - debug it in console with "php bin/console debug:router" and search for "/news/why" in the output. Maybe your route has some prefix you forgot about :)
If nothing helped, please, double sure you use the correct namespace: "Symfony\Component\Routing\Annotation\Route". But it may depend on your Symfony version. For older version you probably need to use this one: "Sensio\Bundle\FrameworkExtraBundle\Configuration\Route" - at least you can try to use this one, but not for the latest version.
Cheers!
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"sensio/framework-extra-bundle": "^5.1", // v5.1.3
"symfony/asset": "^4.0", // v4.0.3
"symfony/console": "^4.0", // v4.0.14
"symfony/flex": "^1.0", // v1.17.6
"symfony/framework-bundle": "^4.0", // v4.0.14
"symfony/lts": "^4@dev", // dev-master
"symfony/twig-bundle": "^4.0", // v4.0.3
"symfony/web-server-bundle": "^4.0", // v4.0.3
"symfony/yaml": "^4.0" // v4.0.14
},
"require-dev": {
"easycorp/easy-log-handler": "^1.0.2", // v1.0.4
"sensiolabs/security-checker": "^5.0", // v5.0.3
"symfony/debug-bundle": "^3.3|^4.0", // v4.0.3
"symfony/dotenv": "^4.0", // v4.0.14
"symfony/monolog-bundle": "^3.0", // v3.1.2
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.0.3
"symfony/profiler-pack": "^1.0", // v1.0.3
"symfony/var-dumper": "^3.3|^4.0" // v4.0.3
}
}
I'm at "omg my first page already" and I'm following along/started the project by myself, and I have this error loading index.php:
Parse error: syntax error, unexpected '?' in C:\www\eds-www\tuts\the_spacebar\public\index.php on line 15
Here's line 15-17 of index.php:
`if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) {
}`
What have I fouled up?