Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Annotations

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.

We've got a big project today, a site about movies. But only movies that have Samuel L. Jackson.

Tip

The "Controller" option when you create a new file is no longer available. However, you can use php bin/console make:controller from MakerBundle as an even nicer option.

We'll start by creating a MovieController. We could right click on the Controller directory, go to new, and select file from the menu. But we can be faster! For Mac users, use +N to get the "new" menu open. And because we have the Symfony Plugin, by typing 'controller' you'll find an option to create one directly. Let's keep things simple and obvious and call it MovieController.

<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class MovieController extends Controller
{
public function indexAction($name)
{
return $this->render('', array('name' => $name));
}
}

Ah, and when you use Git, PHPStorm asks you whether you want to add new files to git. I prefer to just do this myself so I'll click 'no'. Beautiful!

Auto-complete Annotations

We'll need a route to this MovieController, so add some annotations above indexAction(). Let's change these to @Route and let autocomplete do its thing. The one we want is Sensio\Bundle\FrameworkExtraBundle\Configuration\Route, select that option and hit tab and notice that it added a use statement on line 5:

... lines 1 - 4
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
... lines 6 - 7
class MovieController extends Controller
{
/**
* @Route("/movies/new")
*/
public function newAction()
... lines 14 - 16
}

That's really important because when you use annotations you need to have a use statement for them. Now instead of spending your time looking it up in the documentation, autocomplete will take care of it for you. Robots FTW!

Let's have our path be /movies/new and change indexAction() to newAction() because this controller will render a "new movie" form. And we'll fix up our render call in a second:

... lines 1 - 9
/**
* @Route("/movies/new")
*/
public function newAction()
{
return $this->render('', array());
}
... lines 17 - 18

Head over to the browser and check if our new route is hitting our endpoint. Perfect! It can't find the template but that's fine because, there isn't one :)

Annotation Options

Annotations have a lot of options and one of them here is called name, which auto-completes for us. Hey thanks. Fill that in with movies_new:

... lines 1 - 9
/**
* @Route("/movies/new", name="movies_new")
*/
public function newAction()
... lines 14 - 18

If you're the curious sort and are wondering what other options you have, just hold the control key and hit the space bar: that will bring up all the options that you have in that spot. In fact, "control+space" can be used pretty much anywhere to show you your auto-complete option - really handy.

This autocomplete works for two reasons. First, an annotation represents a real class. Hold command, or control if you're in windows, and click @Route to open up the class that fuels it.

... lines 1 - 11
namespace Sensio\Bundle\FrameworkExtraBundle\Configuration;
... lines 13 - 19
class Route extends BaseRoute
{
... lines 22 - 43
}

If you hold command again and go into its base class, you'll see that all of those options are represented as properties inside of that class:

... lines 1 - 11
namespace Symfony\Component\Routing\Annotation;
... lines 13 - 21
class Route
{
private $path;
private $name;
private $requirements = array();
private $options = array();
private $defaults = array();
private $host;
private $methods = array();
private $schemes = array();
private $condition;
... lines 33 - 181
}

To take this further if you go back to MovieController you can hold command and click on the name option and have it take you right to that property. You may not need this very often, but sometimes it's useful to see how an annotation option is used to figure out what value you want to set for it.

Now thanks to the annotations plugin, annotations act a lot more like normal code, with fancy auto-completion and other goodies.

Leave a comment!

28
Login or Register to join the conversation
Jörg daniel F. Avatar
Jörg daniel F. Avatar Jörg daniel F. | posted 1 year ago

Hello,
I install PHP Annotaion 8.0.0, Symfony Support 0.22.206 and PHP Toolbox 5.1.1. But when I try command + n and search for "controller" I find nothing,
PHP storm vers. 2020.3
maybe I forgot something to install?

1 Reply

Hey @Jörg Daniel Fluck!

Hmm, indeed! It looks like this shortcut is gone now! Thanks for letting us know (this tutorial is... unfortunately... getting a little old). There IS a a bin/console make:controller command from MakerBundle you can use to generate controllers, however. I hope that helps :).

Cheers!

Reply
Default user avatar
Default user avatar Boran Alsaleh | posted 4 years ago

Hello ,

I have installed the PHP Annotations By PHPSTORM , but when I want to use auto complete Feature Of ORM Annotations , it gives me No suggestion , I don't know where is the problem ?

1 Reply

Yo Boran,

Try to update PhpStorm to the latest version, then upgrade Symfony Plugin and restart PhpStorm - it should help. Also, please, make sure you enable Symfony Plugin in preferences and paths you have there are correct according to your Symfony directory structure.

Cheers!

Reply
Michael O. Avatar
Michael O. Avatar Michael O. | posted 2 years ago

Hi, Similar to Boran 2 years ago. My entity annotations are fine, but my `@Route` annotations are not autcompleting. Have the latest PHPStorm, Annotations and Symfony plugins with 5.1.2, but nothing in the Controller autocompletes.

Reply

Hey Michael O.

That's weird, could you double check that you imported the right @Route class? Another thing that may help is to re-index your project through PHPStorm, inside Symfony plugin settings, click on the "Clear index" button

Cheers!

Reply
Michael O. Avatar

Hi Diego, sorry late reply but yeah I have done all of these steps and all of the extra steps (invalidating cache, cleared index, reinstall all plugins and made sure the correct @Route class is used (Symfony\Component\Routing\Annotation\Route). Have setup the paths for Symfony plugin for 5.1 as follows:

Translation Root Path: ./var/cache/dev/translations/
App Directory: ./config/
Web Directory: ./public/

It feels as though the plugin is still trying to use the FrameworkBundle @Route in some way as when I start typing 'me' for method in the controller annotations, tab completion tries to insert @Method(""). Still no suggestions when ctrl+space while the caret is in the below position:


/**
* @Route("test", name="test_route", <caret>)
*
*/
Reply

Hey Michael O.!

Hmmm. I think you may have discovered an issue with the "PHP Annotations" plugin! Because, this no longer works for me either. I've opened an issue about it - https://github.com/Haehnche...

The good thing is that (at least for me) all other annotations (e.g. @ORM\Column) seem to work just fine. This seems to only affect @Route.

Cheers!

Reply
Michael O. Avatar

Hi Ryan

Cheers, at least happy(ish) that someone can reproduce!

One thing though, It seems that its not just the @Route annotation not working, but any annotation outside the Entity, e.g. @Security/@ParamConverter etc.

Reply
Steven L. Avatar
Steven L. Avatar Steven L. | posted 2 years ago

When I access localhost:8000/movies/new with the MovieController.php file code copied from the script, or typed by hand, it returns a 404 on "/movies/new" rather than a 500 error relating to the template, and the steps on the next chapter don't work because it's still 404'ing and not finding the page.

OSX 10.5.4, PHP 7.3.11 (stock OSX), Composer 1.10.6, Phpstorm 2020.1, code downloaded from the "download" link above and starting in the "start" directory with "/usr/bin/php -S localhost:8000":

[me@mac start]$ /usr/bin/php -S localhost:8000
PHP 7.3.11 Development Server started at Mon May 11 17:56:33 2020
Listening on http://localhost:8000
Document root is /Users/me/Sites/code-phpstorm/start
Press Ctrl-C to quit.
[Mon May 11 17:56:38 2020] [::1]:63905 [404]: /movies/new - No such file or directory

Reply

Hey Steve,

Are you in dev or prod Symfony environment? It's always a good idea to try to clear the cache first, it should help in most cases. To clear the cache, run:

$ bin/console cache:clear

By default it clears the cache for environment set in .env, see APP_ENV. But you can pass --env=prod if in case you want to clear the cache in specific environment (or change "prod" to any env you need). Or you can just remove the cache folder manually, e.g. "rm -rf var/cache/dev" for removing the dev cache.

Does clearing the cache help you? Or you still have this problem with 404 error? If still the same 404 - I'd recommend you to debug your routes with

$ bin/console debug:router

Do you see that "/movies/new" route there? probably you made a typo in that path?

Cheers!

Reply
Steven L. Avatar

Hi Victor, thanks for the response.

I'm bootstrapping in from zero with this course, and there's been no mention so far of dev/prod, but according to output below I'm in dev.

Console doesn't work from PHP 7.3, and there's no bin directory in this project, but I presume you mean app/console. I ran that with PHP 7.2 to clear the cache, but it didn't fix the 404 error. Manually purging app/cache didn't either.

Debugging the route as you described shows the following:

[me@mac start]$ /Applications/DevDesktop/php7_2_x64/bin/php app/console debug:router | grep movies
movies_new ANY ANY ANY /movies/new

Doesn't appear to be a typo, and it still 404's. Here's a copy and paste of the code (sorry for the formatting, the form mangles the indents and line spacing on copy and paste and there's no preview mode)


namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MovieController extends Controller
{
/**
* @Route("/movies/new", name="movies_new")
*/
public function newAction()
{
return $this->render('movie/new.html.twig', array());
}
}

Reply

Hey Steve,

Ah, yes, then you should be in dev mode, especially if you see Symfony Web Debug Toolbar below the page. But that's really weird... So, the "debug:router" console command does show that you have "movies_new" route, and it does have "/movies/new" URL. So, it should not be a 404 error. Are you sure you're calling the right host in the browser? Probably you have a several projects spinning on your computer? Make sure that your web server is started, and that the URL in your browser: both host and port - are match the host and port in your browser.

Btw, do you see a Symfony 404 error or webserver's 404 error? Symfony's 404 error should be styled nicely and contains Symfony Web Debug Toolbar at the bottom with a lot of useful info. Probably you just forgot to start your web server? Does the homepage works for you or you also see 404 error when open "/app/example" homepage route?

I see you downloaded the course code and started from start/ directory, right? Did you do "composer install" or "composer update" to install dependencies? In newer version of Symfony "use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;" annotation does not work and should be replaced with "use Symfony\Component\Routing\Annotation\Route;" instead. Probably it's worth to try and see if it helps.

Cheers!

Reply
Steven L. Avatar

Thanks Victor. I'm at my wits' end here; I can't get it working.

I am sure that the webserver is running and I'm hitting the right port. I stopped all services and moved it to port 8005 just to make sure it wasn't hitting some other unknown process on port 8000; accessing localhost:8005/ in the browser with the server off results in the browser's "unable to connect to server" message, which is right. I then start the server and hit it again, and I get the 404, from PHP directly (not Symfony). The terminal output shows the 404s being generated:


[slinberg@fifteen start]$ /Applications/DevDesktop/php7_2_x64/bin/php -S localhost:8005
PHP 7.2.22 Development Server started at Wed May 13 20:07:34 2020
Listening on http://localhost:8005
Document root is /Users/slinberg/Sites/code-phpstorm/start
Press Ctrl-C to quit.
[Wed May 13 20:07:40 2020] ::1:49971 [404]: / - No such file or directory
[Wed May 13 20:07:40 2020] ::1:49972 [404]: /favicon.ico - No such file or directory
[Wed May 13 20:07:51 2020] ::1:49974 [404]: /movies/new - No such file or directory

I get the same error on "/" - "app/example" - as I do for "/movies/new" or any other random nonsense path I enter. The browser shows:


Not Found
The requested resource /movies/new was not found on this server.

I did "composer install" initially, but ran "composer update" just now and it updated a lot of packages. I cleared the cache and tried again, but it didn't change the result. I also changed the Sensio line to Symfony\Component\Routing\Annotation\Route as you described, same results. I've run the server with PHP 7.2 and 7.4, same results.

I think I'm just going to scrap everything and start over, but this is pretty frustrating. Can you confirm that the current code download works correctly for you starting with a clean install?

Reply
Steven L. Avatar

OK, I figured it out. It doesn't work if you start the webserver with "php -S localhost:8000". It only works if you start it with "php app/console server:run".

This isn't mentioned in the video or transcript. The end of the first video just says that the server is already running, but not how it was started.

Reply

Hey Steve,

Ah, yes, now I see! Hm, we're sorry for confusing you! Yeah, probably for people who does not use Symfony it's not obvious, I'll think how we can improve this, probably add some notes.

Well, with PHP web server it would work too, but you need to specify docroot like:

php -S localhost:8005 -t web/

In Symfony version we use in this course doc root should be web/ directory inside your project dir.

Sorry I didn't noticed that you start the PHP webserver different :/

Cheers!

Reply
Steven L. Avatar

Hi Victor. Maybe as I continue to go through this I'll trip across other things that are non-obvious to someone without a strong prior background in Symfony. I'll let you know as I go of course.

I did wonder if it might be related to the webroot path, but I tried just now out of curiosity to start the webserver with just PHP and it's still 404'ing:


[slinberg@fifteen start]$ /Applications/DevDesktop/php7_2_x64/bin/php -S localhost:8005 -t web
PHP 7.2.22 Development Server started at Thu May 14 09:13:50 2020
Listening on http://localhost:8005
Document root is /Users/slinberg/Sites/code-phpstorm/start/web
Press Ctrl-C to quit.
[Thu May 14 09:14:03 2020] ::1:52801 [404]: /movies/new - No such file or directory
^C

I also tried starting php within the "web" directory itself without the -t directive and it still also didn't work. I'm glad to hear that it SHOULD - in production I'll be running nginx and I don't think I want to start a server either via PHP or Symfony - but though it's not urgent at this point I would like to figure out what's wrong. Any other ideas?

Reply

Hey Steve!

Yes, it would be much appreciated, thank you!

Yeah, it's not so easy with built-in PHP web server, you have to specify the index file. By default, it works with index.php, but if your front controller has a different name - app.php in our case - you have to pass it explicitly. So, if you run the server with:

$ php -S localhost:8005 -t web/

Try http://localhost:8005/app.php/movies/new or http://localhost:8005/app.php/app/example - it should work this way. That's why using Symfony built-in web server is more convenient. However, even Symfony built-in web server is not recommended lately. Nowadays Symfony community has even better solution called Symfony CLI (or Symfony local web server) - see https://symfony.com/doc/cur... - it even allow you using HTTPS out of the box, but you need to install certs first. And yes, you can use it not only for Symfony projects. If you're interested - read the docs. We use it in all our recent tutorials.

Cheers!

Reply
Steven L. Avatar

Thanks Victor, getting back to this today. You're right that starting the server with PHP and then going through the path /app.php/movies/new works 👍 It just displays a 500 internal server error (expected at this point in the course, so it's OK), but of course without the nice symfony wrapper that actually shows the error and related information. In any event, I'm planning to run production under nginx, so I guess I don't need to lean into this too hard... but it seems preferable to run dev at least with the symfony server for the toolbar, which I assume you can't get any other way?

Reply

Hey Steve,

That's because app.php front controller is for prod mode. If you want to run the website in dev mode, run /app_dev.php/movies/new instead. On your production, you will need to point your Nginx web server to exactly "app.php". Actually, for security reasons, it's recommended to remove all front controllers from web/ dir except the app.php.

Btw, Symfony version that is used in this course is old. The new Symfony version has only one front controller called index.php and allow you to switch Symfony env with environment variables.

Cheers!

Reply
sitegeist Avatar
sitegeist Avatar sitegeist | posted 3 years ago

Just a little update: for the annotations the Symfony\Component\Routing\Annotation\Route class should be used, because the Sensio\Bundle\FrameworkExtraBundle\Configuration\Route class is depricated (since version 5.2 of the FrameworkExtraBundle package)

Reply

Hey sitegeist

That's correct! Thanks for sharing it :)

Cheers!

Reply
Default user avatar

For Mac User they use Apple + N. How about windows users with PHP Storm?

Reply

Hey Craig!

Try using "Alt + Insert" it should do the trick
Also if you open your settings and serach for "keymap" you will find all the shortcuts defined and you can even create your owns!

Have a nice day!

Reply
Default user avatar
Default user avatar Farnoosh | posted 4 years ago

For Apple user is Ctrl+N

Reply

Hey Farnoosh,

For Apple users, by default, "Code Generate" could be called with Command + N (or Ctrl + Enter as fallback), but it really depends. However, you can totally change it in PhpStorm settings: "PhpStorm" -> "Preferences" -> "Keymap". Also, on the first launch you could choose a different keyboard tempalte (keymap), for example, to match NetBeans IDE keyboard shortcuts, etc. And I suppose it could even depend on PhpStorm's version :)

Cheers!

Reply
Default user avatar
Default user avatar Shairyar Baig | posted 4 years ago

It will really be great if you can create a tutorial for github like how to use it for version control and all

Reply

that would be a whole different topic! and way to vast to really consider making a screencast series.
https://git-scm.com/book/en/v2 <- check that url, its a great git guide.

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This is an older tutorial using an older version of PhpStorm. However, most of the tricks we show in PhpStorm still work beautifully.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.3.9, <7.3.0",
        "symfony/symfony": "2.8.*", // v2.8.15
        "doctrine/orm": "^2.4.8", // v2.4.8
        "doctrine/dbal": "<2.5", // v2.4.5
        "doctrine/doctrine-bundle": "~1.4", // 1.6.4
        "symfony/assetic-bundle": "~2.3", // v2.8.1
        "symfony/swiftmailer-bundle": "~2.3,>=2.3.10", // v2.4.2
        "symfony/monolog-bundle": "^3.0.2", // v3.0.2
        "sensio/distribution-bundle": "~5.0", // v5.0.17
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.18
        "incenteev/composer-parameter-handler": "~2.0" // v2.1.2
    },
    "require-dev": {
        "sensio/generator-bundle": "~3.0", // v3.1.2
        "symfony/phpunit-bridge": "~2.7" // v2.8.15
    }
}