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.

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!

  • 2020-06-19 Diego Aguiar

    Hey Michael O'Toole

    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!

  • 2020-06-18 Michael O'Toole

    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.

  • 2020-05-19 Victor Bocharsky

    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!

  • 2020-05-17 Steve Linberg

    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?

  • 2020-05-15 Victor Bocharsky

    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!

  • 2020-05-14 Steve Linberg

    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?

  • 2020-05-14 Victor Bocharsky

    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!

  • 2020-05-14 Steve Linberg

    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.

  • 2020-05-14 Steve Linberg

    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?

  • 2020-05-13 Victor Bocharsky

    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!

  • 2020-05-12 Steve Linberg

    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());
    }
    }

  • 2020-05-12 Victor Bocharsky

    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!

  • 2020-05-11 Steve Linberg

    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

  • 2019-09-20 Diego Aguiar

    Hey Waldemar Kunz

    That's correct! Thanks for sharing it :)

    Cheers!

  • 2019-09-20 Waldemar Kunz

    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)

  • 2018-02-12 Victor Bocharsky

    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!

  • 2018-02-11 Boran Alsaleh

    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 ?

  • 2017-07-27 Victor Bocharsky

    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!

  • 2017-07-26 Farnoosh

    For Apple user is Ctrl+N

  • 2017-04-21 Diego Aguiar

    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!

  • 2017-04-21 Craig

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

  • 2016-06-13 JLChafardet

    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.

  • 2015-08-04 Shairyar Baig

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