Form Type Class

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.

Hey friends! And welcome to, what I think will be, a super fun tutorial: the one about cookies! Um, forms!

The first question you might ask is: forms? Do we even need forms anymore in this age of JavaScript frontends? Aren't forms so 2016? The answer is... it depends. I get to talk to a lot of developers and, honestly, it comes down to what you're building. Yea, some apps are using modern JavaScript frontends. But just as many are building form-rich interfaces. So, if that's you - hi! o/.

There is no more powerful form system on the planet than Symfony's Form component. Oh, and there are so many pieces to a form: rendering the form, handling the submit, validating data, normalizing data, and other things that you don't even think about, like CSRF protection. Here's the truth about Symfony's Form component: yes, it is crazy powerful. And when you learn to harness that power, you will be incredibly productive. At the same time, in some situations, the form system can be really hard & complex. It can make your job harder than if you didn't use it at all!

So here is our big goal: to learn how to do almost everything you can think of with a form and to identify those complex scenarios, and find the simplest path through them. After all, even if you use and love the form system, it doesn't mean that you have to use it in every single situation.

Project Setup

As always, to become the master of form tags, inputs & textareas, you should totally code along with me. Download the course code from this page. When you unzip it, you'll find a start/ directory inside with the same files that you see here. Open up the file for instructions on how to get the site set up. The last step will be to find a terminal, move into the project, sip some coffee, and run:

php bin/console server:run

to start the built-in web server. Woo! Now, find your browser and head to http://localhost:8000. Welcome to our work-in-progress masterpiece: The Space Bar! Our intergalactic news site where aliens everywhere can quickly catch up on only the most important news... after a 500 year nap in cryosleep.

Thanks to our last tutorial, we can even log in! Use, password engage. Then head over to /admin/article/new to see.... oh! A big TODO!

Yep! We can display articles but... we can't actually create or edit them yet. The code behind this lives in src/Controller/ArticleAdminController.php and, sure enough, past us got lazy and just left a TODO.

Creating a Form Class

Time to get to work! The first step to building a form is always to create a form class. Inside src, add a new Form/ directory... though, like normal, you can put this stuff wherever you want. Inside, a new PHP class called ArticleFormType. Form classes are usually called form "types", and the only rule is that they must extend a class called AbstractType. Oh! But of course! I can't find that class because... we haven't installed the form system yet! No problem!

Find your terminal, open a new tab, have another well-deserved sip of coffee, and run:

composer require form

Perfect! Back in our editor, once PhpStorm finishes indexing, we should be able to find the AbstractType class from the Form component.

Got it! Now, go to the Code -> generate menu, or Cmd+N on a Mac, and click override methods. There are several methods that you can override to control different parts of your form. But, by far, the most important is buildForm().

... lines 1 - 4
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ArticleFormType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)

Inside this method, our job is pretty simple: use this $builder object to, um... build the form! Use $builder->add() to add two fields right now: title and content. These are the two most important fields inside the Article entity class.

... lines 1 - 9
public function buildForm(FormBuilderInterface $builder, array $options)
... lines 17 - 18

And... that's it! We'll do more work here later, but this is enough.

Creating the Form Object

Next, find your controller so we can render the form. Start by saying $form = and using a shortcut: $this->createForm(). Pass the class that you want to create: ArticleFormType::class. I'll delete the return response stuff and, instead, render a template with return $this->render('article_admin/new.html.twig'). To render the form, we need to pass that in. Let's call the variable articleForm and set it to - this is tricky - $form->createView(). Yep: don't pass the $form object directly to Twig: always call createView(). This transforms the Form object into another object that is super good at rendering forms and telling funny stories at parties.

... lines 1 - 12
class ArticleAdminController extends AbstractController
... lines 15 - 18
public function new(EntityManagerInterface $em)
$form = $this->createForm(ArticleFormType::class);
return $this->render('article_admin/new.html.twig', [
'articleForm' => $form->createView()
... lines 27 - 35

Rendering the Form

To create the template, I'll cheat! Ha! Thanks to the Symfony plugin, I can put my cursor on the template name, hit alt+enter, click "Create Twig Template" and hit enter again to confirm the location. There's no real magic here: that just created the file for us at templates/article_admin/new.html.twig.

Oh, and you might remember from previous tutorials that, in addition to the normal base.html.twig, we also have a content_base.html.twig, which gives us a little bit of real markup and a content_body block that we can override. Let's use that: {% extends 'content_base.html.twig %} and then, override the block content_body, with {% endblock %}. Add an <h1>Launch a new Article</h1> with, of course, a rocket emoji! Zoom!

{% extends 'content_base.html.twig' %}
{% block content_body %}
<h1>Launch a new Article! ?</h1>
... lines 5 - 10
{% endblock %}

To render the form, we get to use a few special form rendering functions: {{ form_start() }} and pass that the articleForm variable. At the end {{ form_end(articleForm }}. And in the middle, {{ form_widget(articleForm) }}. Oh, and for the submit button, you can build this into your form class, but I prefer to add it manually: <button type="submit">, some classes: btn btn-primary, and then Create!

{% extends 'content_base.html.twig' %}
{% block content_body %}
<h1>Launch a new Article! ?</h1>
{{ form_start(articleForm) }}
{{ form_widget(articleForm) }}
<button type="submit" class="btn btn-primary">Create!</button>
{{ form_end(articleForm) }}
{% endblock %}

And... we're done! We create a form class, create a Form object from that in the controller, pass the form to Twig, then render it. We'll learn a lot more about these rendering functions. But, more or less, form_start() renders the opening form tag, form_end() renders the form closing tag... plus a little extra magic, and form_widget() renders all of the fields.

Try it! Find your browser and refresh! Woohoo! Just like that, we have a functional form. Sure, it's a bit ugly - but that will be super easy to fix. Before we get there, however, we need to talk about handling the form submit.

Leave a comment!

  • 2020-05-13 mcc2


  • 2020-05-12 Vladimir Sadicov

    Hello mcc2

    Thanks for reporting this issue, it was just fixed, so you only need to re-download course code and continue crushing this course! If you are interested it was caused by twig library version.


  • 2020-05-11 Vladimir Sadicov

    Hey mcc2

    Just to clarify do you use PHP 7.4?


  • 2020-05-09 mcc2

    Hi, I have an interesting problem with this. For another project it was not an issue but downloading this course files there is an issue with the form. When the form is rendered, there is a mistake that <div id="article_form"> renders as <divid="article_form">. Therefore, broking the whole HTML code. The code is just as downloaded from your course. Do you have an idea why is it so?

  • 2020-03-05 weaverryan

    That's exactly right - thanks for posting Damir Vakhitov! This error means that your PHP install doesn't have the PDO extension. How you install this depends on your system - you can use apt-get in Ubuntu or brew on a Mac (if you're using Brew).

    Let us know if that helps!


  • 2020-03-03 Damir Vakhitov

    It seems you need to include PDO driver in php.ini.

  • 2020-03-02 Vladimir Sadicov

    Hey Mantas Zv

    Can you provide more details? Like php version? MySQL version? Also can you check if mysql extension is enabled in PHP.


  • 2020-03-02 Mantas Zv

    I have a problem launching project. Opening web I get red Symfony error window: "PDOException >PDOException> DriverException", "An exception occurred in driver: could not find driver". In server terminal i see: many lines with PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /home/.../code-symfony-forms/start/vendor/michelf/php-markdown/Michelf/Markdown.php on line [955...1801] and MarkdownExtra.php line [215...1469] and red error: [500]: GET /

  • 2019-11-13 Victor Bocharsky

    Hey Dung,

    Yeah, I just gave you an idea about how to workaround it. OK, so Slack is no go with this, but WhatsApp helps, good to know! Thank you for your feedback, and I'm glad it works with WhatsApp at least :)


  • 2019-11-12 Dung Le

    Hello Victor Bocharsky the slack uses its own library and Does Not work
    @Damir Vakhitov's solution is correct, tested and it works!

  • 2019-11-11 Victor Bocharsky

    Hey Dung,

    Great! Would be happy to get your feedback if it works for you or no. I didn't try this on Windows, so just curious about it :)


  • 2019-11-11 Dung Le

    Great, I did not know I could get it from Slack, I use Slack everyday :). Will definitely try it!
    Thanks Victor Bocharsky

  • 2019-11-11 Victor Bocharsky

    Hey Dung,

    Thank you for letting us know you've got the answer yourself! Yeah, that feature is something unique for Mac I suppose. As a workaround, I can suggest to try to copy/paste emoji from apps that support them internally and that you use every day. For example, I believe you can copy the emoji from Slack application and paste them in PhpStorm. Slack have native support for emoji IIRC, so I suppose it should work this way.

    I hope this helps!


  • 2019-11-10 Dung Le

    I found the answer here but it is nothing like Mac OS, so please Victor Bocharsky ignore my question - it may be good for someone who uses emojis heavily on Windows but not when I rarely use it.

    I will just use it the way @Damir Vakhitov suggested open web whatsapp copy and paste occasionally. Thanks!

  • 2019-11-10 Dung Le

    Hello Victor Bocharsky how are you,

    I am on Windows developing in Phpstorm, how can I get the rocket emoji the same way as in Mac?

    Thank you and you have a wonderful day!

  • 2019-10-28 weaverryan

    Hey @Rudolph!

    Sorry for the slow reply. Hmm. You downloaded the new project from this page, right? Did you update any dependencies? The error is definitely odd :). What's stranger is the error, specifically this part:

    > Argument 1 passed to AbstractToken::__unserialize() must be of the type array

    If you look at the signature of this method, it at least makes sense:

    public function __unserialize(array $data): void

    Well, I man, I can't explain the error - but you can see the array type hint on the first argument. BUT, that code is from Symfony 4.4. This project uses Symfony 4.1, and if you look at this method in 4.1 (or in the downloaded code), it does *not* yet have that array type-hint.

    So, did you update any dependencies? Or is this an exact copy of the downloaded code? I couldn't (at least on my php version) reproduce this error by downloading the course code and testing the start directory :).


  • 2019-10-22 Rudolph Harry

    This what happens when I try to connect me via the login page.

  • 2019-10-22 Rudolph Harry

    I have a problem when I download the new project in the beginning of the video. I have this error:
    Argument 1 passed to Symfony\Component\Security\Core\Authentication\Token\AbstractToken::__unserialize() must be of the type array, string given, called in /Applications/MAMP/htdocs/EmarhAgence/vendor/symfony/security-guard/Token/PostAuthenticationGuardToken.php on line 87

  • 2019-08-12 Victor Bocharsky

    Hey Damir,

    Thank you for this tip, really an easy way ;) Also, if you're on a Mac, you can press "Ctrl + Command + space" to get a popup with emoji - might be a good and short trick for Mac users.

    Though, it might still be not helpful for Camille if he doesn't have a proper font in his system I think.


  • 2019-08-07 Damir Vakhitov

    Open "web whatsapp", find roket smile, copy and past. 🚀

  • 2019-07-14 Mike

    Yeah that would be great!

  • 2019-06-20 Diego Aguiar

    Yep! Don't forget to define its namespace :)
    And also, just to be aware of, file name and class name must be the same


  • 2019-06-20 Michael Leblanc

    If you have an error similar to this :
    The autoloader expected class "App\Forms\ArticleFormType" to be defined in file "/var/www/html/vendor/composer/../../src/Forms/ArticleFormType.php" .......

    Check if you have correctly enter your namespace in ArticleFormType !

  • 2019-04-26 Vladimir Sadicov

    He Camille Seuvin

    Not tools, but Font, it should be installed on your system, Try to find osx emoji font for linux


  • 2019-04-26 Camille Seuvin


    Which tools do you use to insert your emoji?

    The emoji I copy/paste in my editor does not appear on my web page (an empty rectangle appears) and if I use unicode code, the emoji is in black and white.

    (I work under linux mint and with phpstorm)


  • 2019-02-25 weaverryan

    Hey bz!

    You're 100% right - thanks for the tip! Using the 255 + length causes this error in specific versions of MySQL (and apparently also mariadb). We're going to check into updating the code to use the shorter length so that nobody hits an issue.


  • 2019-02-22 bz

    When running bin/console doctrine:migrations:migrate on mariadb-server-10.1 (and probably MySQL 5.6) you'll get an error:

    SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

    This is related to the length (255) of the `slug` column in table `tag`, in combination with UNIQUE. To avoid having the issue change the field to VARCHAR(190) in Version20180501142420.php.

    See also

  • 2018-12-07 Fernando Andrade

    I knew about it already :P
    you guys have a lot of good content :)

  • 2018-12-01 Steve

    The MakerBundle is awesome and a huge leap forward. Overriding the makers was far easier than I'd expected it to be, essentially its the template references that I'm changing but am learning a lot about the Makers themselves too.


  • 2018-12-01 weaverryan

    Haha, indeed :). The unofficial way is fine - we just can’t guarantee that, for example, we won’t change variables or how something is generated entirely. But obviously, you realize that - so it’s cool. We don’t change things unnecessarily, but it is possible.

    Hopefully, other than it being harder to override the templates, you like MakerBundle better than the old one - we reallt tried to take it to the next level :).


  • 2018-11-29 Steve

    So its you I need to track down ha ha

    I've taken Vladimir's hint and found an unofficial way to do it. My first step was to change the hard coded template references in the MakerCrud class but I've now created a new command and class, basically copied the default one but with different template references. It seems to be doing just what I need.

    Thanks for all you help


  • 2018-11-28 weaverryan

    Hey Steve!

    Yea, this is ultimately my idea / restriction :). So, we don't have hook points, but if there is some option that you would like to propose (e.g. generating `use strict` on top of all of the generate classes), that is definitely an option we would consider.


  • 2018-11-27 Steve

    Hi Vladimir

    Thank you for replying. I understand your points but in my case point 1 is the opposite. This is going to slow down development, being able to override the SensioGeneratorBundle was fantastic. I will try to find an unofficial way :)



  • 2018-11-26 Vladimir Sadicov

    Hi Steve

    That's a great question, and I have an answer!

    There is no official way to override templates in Maker Bundle and as I know there is no plans to do it in future. You maybe want to know WHY!? And there are 2 big reasons for it:
    1) Allowing templates to be overridden makes maintenance on the bundle much harder because developers need to maintain backwards compatibility. This slows down how fast they can innovate and improve the commands. It was huge problem with SensioGeneratorBundle
    2) Some generated things aren’t even done by a template - but are instead done by the nikic/php-parser - they are done dynamically with PHP code - there’s no easy way to make those things overriddeable

    PS: You can try to find an unofficial way to do it.


  • 2018-11-26 Victor Bocharsky

    Hey Fernando,

    Thank you for your explanation! Sure, I'd do the same - pick those technologies and tools that I'm working on currently or going to work with in the nearest future.

    Great, looks like we have ReactJS course on time for you ;) Here's the link to it .


  • 2018-11-24 Steve

    I might be jumping ahead here but in Symfony 3 I override the SensioGeneratorBundle form, controller and templates to save modifying them each time I generate a new ones.

    Is this possible with the Maker Bundle in a similar way. Any plans to cover this or is there some docs already?



  • 2018-11-23 Fernando Andrade

    regarding the access after the subscription, yeah makes sense :)
    I was just curious anyway :)

    about the forms, Frontend using a single page application speaks with PHP on the back end as a REST API... Since I do not know React, that will be my next tutorial to pick up :)

    At least I do not want to have to deal with such a thing any other way... I may be wrong and if I do, I'll come back to this course ;)

  • 2018-11-23 Victor Bocharsky

    Hey Fernando,

    What do you mean? You don't see a value in Symfony Forms in 2018? Do you have any other alternatives? Just wonder...

    Nope, unfortunately, if you canceled your subscription - you would not have access to finished tutorials. Well, when you cancel your subscription, it's still active until the actual period end, but after it's ended - you don't have access. Only course owners - users who bough separate screencasts instead of subscriptions - will have infinite access to courses they bought.

    I hope this helps! And we glad to had you on board! Good luck with building backends with Symfony4 ;) Feel free to come back whenever you want!


  • 2018-11-23 Fernando Andrade

    I think I'm gonna skip this part completely, honestly I do not see the benefits of this in 2018...

    Thank you guys, gonna go on and build a nice backend with Symfony4, probably I'm going to be back for that wonderful javascript tutorial for PHP devs that you guys have...

    Question tho regarding the subscription, I finished the other tutorials in the Symfony4 track... if for some reason I cancel my subscription do I still have access to them afterwards? just curiosity but we never know the future...

  • 2018-10-30 mouad err

    will be a great idea to add those features to the course

  • 2018-10-29 cybernet2u

    well, you have covered pretty much everything except comments, or how to add comments to an article as logged in user via ajax, or APi
    when adding a comment, the author of post should be notified ... more complex stuff ...
    or working with multiple forms.
    subscribe to a topic & when someone post a new article on space bar, those subscribers will get a email notification...
    there are plenty of stuff

  • 2018-10-29 weaverryan

    Hey cybernet2u!

    That's an interesting idea! In theory, it's not really different than a normal form submit, but perhaps it's different enough that it's worth covering. Is there any part of this specifically that you're most interested in?


  • 2018-10-29 cybernet2u

    how about adding comments ? with AJAX :D