This tutorial has a new version, check it out!

Sharing Form Templates with include()

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

Adding edit was quick! But the entire template is now duplicated. This includes the code to render the form and the other blocks that include the needed CSS and JS files.

First, copy the form rendering code and move that into a new file: _form.html.twig:

{{ form_start(genusForm) }}
{{ form_row( }}
{{ form_row(genusForm.subFamily) }}
{{ form_row(genusForm.speciesCount, {
'label': 'Number of Species'
}) }}
{{ form_row(genusForm.funFact) }}
{{ form_row(genusForm.isPublished) }}
{{ form_row(genusForm.firstDiscoveredAt) }}
<button type="submit" class="btn btn-primary" formnovalidate>Save</button>
{{ form_end(genusForm) }}

Paste it here.

In edit, just include that template: include('admin/genus/_form.html.twig'):

... lines 1 - 22
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Edit Genus</h1>
{{ include('admin/genus/_form.html.twig') }}
{% endblock %}

Copy that, open new.html.twig, and paste it there:

... lines 1 - 22
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>New Genus</h1>
{{ include('admin/genus/_form.html.twig') }}
{% endblock %}

Ok, I'm feeling better. Refresh now: everything still looks good.

And by the way, if there were any customizations you needed to make between new and edit, I would pass a variable in through the second argument of the include function and use that to control the differences.

Using a Form Layout

So let's fix the last problem: the duplicated block overrides.

To solve this, we'll need a shared layout between these two templates. Create a new file called formLayout.html.twig. This will just be used by these two templates.

Copy the extends code all the way through the javascripts block and delete it from edit.html.twig:

... lines 1 - 2
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Edit Genus</h1>
{{ include('admin/genus/_form.html.twig') }}
{% endblock %}

Paste it in formLayout.html.twig:

{% extends 'base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="//">
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="//"></script>
jQuery(document).ready(function() {
format: 'yyyy-mm-dd'
{% endblock %}

So this template itself will extend base.html.twig, but not before adding some stylesheets and some JavaScripts. In edit, re-add the extends to use this template: admin/genus/formLayout.html.twig:

{% extends 'admin/genus/formLayout.html.twig' %}
... lines 2 - 14

Copy that, open new.html.twig and repeat: delete the javascripts and stylesheets and paste in the new extends:

{% extends 'admin/genus/formLayout.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>New Genus</h1>
{{ include('admin/genus/_form.html.twig') }}
{% endblock %}

Try it! Cool! We're using our Twig tools to get rid of duplication!

A Word of Caution

Congrats team - that's it for our first form episode. You should feel dangerous. Most of the time, forms are easy, and amazing! They do a lot of work for you.

Let me give you one last word of warning: because this is how I see people get into trouble.

Right now, our form is bound to our entity and that makes this form super easy to use. But eventually, you'll need to build a form that does not look exactly like your entity: perhaps it has a few extra fields or is a combination of fields from several entities.

When you run into this: here's what I want you to do. Don't bind your form to your entity class. Instead, create a brand new class: I usually put these classes inside my Form directory. For example, GenusModel. This class will have the exact properties that your form needs.

Bind this class to your form and add all your validation rules like normal. After you submit your form, $form->getData() will return this other object. Then, it'll be your job to write a little bit of extra code that reads this data, updates your entities - or whatever else you need that data for - and saves things.

If you have questions, let me know in the comments.

There's certainly more to learn, but don't wait! Get out there and build something crazy cool!

Seeya guys next time!

Leave a comment!

  • 2019-04-04 Diego Aguiar

    If you inspect your form what's the value of the "action" property? Also, try adding some debug information in your controller method so can double check that the route is being hit

  • 2019-04-04 dave

    still does nothing. thanks anyway

  • 2019-04-03 Diego Aguiar

    Hey @dave

    I think I found your problem. You set up the URL action to a "name" property on your form, it should be set on the "action" attribute

    <form action="{{ path('subscribe') }}" ...="">


  • 2019-04-03 dave

    I am trying to make a subscribe form which has to be rendered in the base twig so it can be shown in every page. I have made the view part but I am not reaching the controller.

    This is the view:

    <div class="form-row text-center">
    <div class="col-12">
    <form name="{{" path('subscribe')="" }}="" method="post">
    <input type="text" class="input-field-subscribe" name="subscriber_email" placeholder="Your email" aria-label="Your email" required="" aria-describedby="basic-addon2">
    <input class="btn btn-sm btn-outline-dark my-0" type="submit" value="Subscribe">

    this is the controller:

    * Persists the subscriber.
    * Sends email to verify it.
    * @Route("/subscribe", name="subscribe")
    * @param Request $request represents an HTTP request.
    * @param \Swift_Mailer $mailer is the object that makes possible the delivery of the email.
    * @return \Symfony\Component\HttpFoundation\Response
    * @throws \Exception
    public function subscribe(Request $request, \Swift_Mailer $mailer)
    $subscriber = new Subscribers();
    $email = $request->request->get('subscriber_email');
    $length = 16;
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $random = '';
    for ($i = 0; $i < $length; $i++) {
    $random .= $characters[rand(0, $charactersLength - 1)];

    if ($request->request->get('POST')){
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $this->addFlash('exception', 'Invalid email format.');
    } else {
    $em = $this->getDoctrine()->getManager();
    $this->addFlash('success', 'Verify your email. An email has been sent to you.');


    return $this->render('Subscriber/subscribe.html.twig', [
    //'subForm' => $subscriberForm->createView(),

  • 2018-10-13 Coder

    ok, putting to my watch list as low priority those contribution videos.

  • 2018-10-05 Victor Bocharsky

    Hey Coder,

    I bet Ryan is still alive :) It's always good to get a feedback from developers like YOU, and we have heard you, thanks!

    > I like more giving ideas what needs to be in the documentation.

    Well, of course, that's much easier :p But actually doing things, and doing it good requires some time, you know ;)

    > But I do not writing beatiful texts so that it would fit the documentation...

    Ha, that's exactly the problem of many good developers who think so. But we think you're wrong here. Most important in docs is a good example, and developers like you may see such good examples, that will help other developers a lot. Don't think you need to be an excellent writer for contributing to Symfony docs! Anyway, if something sounds to so good as it could be - someone will reword the text or point you how you can improve it. Btw, I'd recommend you to watch our new screencast about contributing to Symfony: - it's probably much easier than you think right now :)

    > At least if there was a mechanism how to earn money from that, I would maybe consider...

    Well, I see your point, and that's fair, we all need to get money someway for our life, but we're talking about Open Source. Symfony IS an open source software, and a lot of people contribute to it for free, and that's exactly what makes Symfony so popular and awesome! But sure, nobody is forced to contribute to open source, so don't worry about it too much, I bet a lot of people like doing so and we'll continuously improve Symfony and its docs little by little.

    Once again, thanks for the good conversation!


  • 2018-10-05 Coder

    Oh, hopefully you did not die after my criticism about symfony documentation :) maybe I could have used different words, but that would not express so good how I and probalby other developers feel then :)

    I think it is much better to have opinionated information which teaches you to make it work than not opinionated information which causes wasting precious time by trying to figure out how to do a simple thing.

    But I agree that it is to show all posibilities.

    >it would be AMAZING if you made a PR.
    I like more giving ideas what needs to be in the documentation. But I do not writing beatiful texts so that it would fit the documentation :)
    At least if there was a mechanism how to earn money from that, I would maybe consider and others probablty would consider. Now I already have lot of fun things to do in my life, I do not feel that much value of using my time for doing something for free. I understand that I could write to my CV that I contributed to documentation, but unless I contribute a ton, it will not raise my value much.

  • 2018-10-05 weaverryan

    Hey Coder!

    SO glad you're finding the answers you need. And this was a VERY insightful comment - lot's of interesting things here for me! Let me answer a few things:

    > I am sick of symfony writing so bad documenation and so I often hate it for that.

    I'm glad you like SymfonyCasts. But I'm also the lead contributor to the docs :D. We're actually investing a bit more in it right now, so that we can make it better - I agree that it needs big work! The fun thing about SymfonyCasts is that I can be a bit more opinionated about how I think you *should* do things... instead of showing all the possibilities. The docs need to cater to everyone - it's a tough challenge - but we're working on it :).

    > Your video should be in symfony documentation. I am also surprised that there are stack overflow questions where people like me struggle and why nobody posts a link to your videos. Maybe its a problem that too little amount of people know it - seo problems?

    This is very interesting :). Of course, I would also like more people to link to SymfonyCasts! But, there may be a simple explanation for the SEO problem - about 3 weeks ago, we completely renamed our domain. Yes, we have 301 permanent redirects, etc. But, I think that our SEO has temporarily (hopefully temporarily) suffered. We've noticed that the site is now coming up way lower in certain search terms, after the domain change. I'm hoping that will correct itself soon, as we've done everything (that I know of) that you're supposed to do when renaming a domain, for a smooth transition.

    > Good job. Btw, how much time if its not secret you spend to learn those things which you make on those videos with no information? Or you have some secret source of good tutorials for yourself ?:D

    Ha! A lot of time :p. But actually, it's because I work on Symfony itself... so I already spend a lot of time learning it... by contributing to it. However, sometimes when I'm not an absolute expert on something, we'll partner with someone that is. It's all about finding GREAT people who know some technology well, then explaining in simple terms to the rest of us (which often includes me!)

    > Maybe now I should myself update the documentaion which I hate by adding link to your video. But I am not even sure if they accept and I think bit too much beurocracy to contribute,

    I'm happy to say that there are already links to SymfonyCasts on the documentation. But, there could be more! If there is a spot in the docs where one of our screencasts would fit in nicely, it would be AMAZING if you made a PR. About 3 weeks ago (the domain rename) we became an official partner with Symfony - adding appropriate links is not a problem.

    Thanks for the interesting chat!


  • 2018-10-04 Coder

    Watched already 11 videos and after this video its clear how it works ! wow. I am sick of symfony writing so bad documenation and so I often hate it for that.
    But I know that many companies and good developers use it, so I need to learn it, and I myself often work in companies which use it. You are the example how the documentation should look like.
    I do not get why developers have to waste so much time for doing simple stuff like passing a variable to template. Your video should be in symfony documentation. I am also surprised that there are stack overflow questions where people like me struggle and why nobody posts a link to your videos. Maybe its a problem that too little amount of people know it - seo problems? When I searched on stack overflow, I really should have been pointed to watch those videos first and then I believe many problems would have been solved. Now those comments might be useful for seo maybe, but I heard that discuss somehow does not help for seo. And really - tried to search for "Hey guys! My Symfony app is growing in content and my users are requesting a search bar. " which was commented 2 months ago and google does not give the link to this video. I am not sure which fault is that - google or disqus. I really like disqus platform, its so easy to see all your comments, but it really sucks when it does not add to google search. Maybe there is some similar alternative and you should consider?

    Good job. Btw, how much time if its not secret you spend to learn those things which you make on those videos with no information? Or you have some secret source of good tutorials for yourself ?:D

    Maybe now I should myself update the documentaion which I hate by adding link to your video. But I am not even sure if they accept and I think bit too much beurocracy to contribute, at least it was my first impression when some time ago I tried, so not feeling motivated to do so.

  • 2018-10-04 Coder

    Oh, yea, I saw this, but I did not want to watch about form themes, because I think I even saw some talk where themes were not recommended and they are way too complicated. But maybe I need to watch this, maybe at least I will learn about form types. And in a project where I work there are some places where themes are used so will not hurt to know better about them.

  • 2018-10-03 weaverryan

    Hi Coder!

    That's all very fair feedback :). We actually *might* have a course that covers what you are talking about - it is

    It talks about form view variables, how they interact with form type "options" and more. Check it out - let me know if it helps :).


  • 2018-10-03 Coder

    Hello, I did not read the discussion. But for me this what you have showed in this course looks basic and like 80 % I knew. But the problem is that I still struggle with forms. For example recently struggled with form types. Getting various errors and not knowing how to fix, how to debug. Reading symfony documentation also did not help. Like here:

    I recently spent like 5 hours and was not able to pass custom variables to template of custom form type. Passed them as html data attribues, but there is options array, so it should be possible to pass them thought that array.

    I think you should do a tutorial on this. Or maybe there exists one but I just did not find?

    Plus you could make a course of how to debug forms. You can make intentionally various errors which developers have and show a way how we should debug - from the moment when we have no idea how to do it and googling does not help, because there are too many various situations and what you triy from stack overflow answers does not help.

  • 2018-07-26 Diego Aguiar

    Hey Cesar Delgado

    For that task you don't actually need to use Symfony's form system, you can render and process one manually, you only need a text input and a way to submit (by pressing enter key). So, in your template just add a block with that HTML that will be included in your base template (so it will be shown on every page), then the submit action will be handled by a custom controller's action where you will be able to add all the logic that you need.

    If you still have doubts about how to implement it, just let us know!

    Have a nice day.

  • 2018-07-25 Cesar Delgado

    Hey guys! My Symfony app is growing in content and my users are requesting a search bar. So, i have some questions:

    - How can I have a form in every page? Do I need to put the form and logic in a service?
    - If the search form is in every page, in some pages I will have more than one form. For example, in my contact page. How can I manage two forms in the same page?
    - Maybe you know a good bundle for this? I think this is a common request.

    I hope you can help me. I would appreciate any tip.


  • 2018-01-22 Diego Aguiar

    Hey @Cesar!

    Sorry for the late response, I'm happy to hear that you managed to overcome your problem. About rendering multiple forms in a Twig template, that's totally possible and is ok to do it.
    If you have more doubts you can contact us any time :)


  • 2018-01-21 Cesar

    Don't worry anymore Diego. I found this and I have used it. I am not sure that I understood everything but it's working in my application. Thanks for your help.

  • 2018-01-19 Cesar

    Hi Diego. Even if I use Javascript, how I can handle the Request in the Controller? Do you have an example of this? It will be really helpful. Also, there is no way to render more than one form in the same page using Twig or the Form Component?

  • 2018-01-18 Diego Aguiar

    Hey @Cesar

    How familiar are you with Javascript? Because what I would do is, request that form (via AJAX) whenever a user clicks on a button, then you could add a data attribute to the button to distinguish which button was pressed, so you can choose correctly which form to render or process.


  • 2018-01-17 Cesar

    Hi Ryan. Thanks for answer me. Imagine there are three buttons on the page and when you clic on each of them it will appear a form in a pop-up (modal). The only difference between those three are the options in one field. So, the url can not change (it's the same page) and the user only need to save one form depends in which button he chose. Do you have any idea how to solve this? I will appreciate your help.

  • 2018-01-17 weaverryan

    Hey Cesar!

    Hmm. I will say 2 things :).

    1) You *can* create a single Form class that is capable of creating all 3 forms. The tricky part is: inside buildForm, you need to know *which* form you are building so that you can configure the EntityType correctly. To do that, you can add a custom option to your form - e.g. entity_user_option (that's a terrible name, but I don't know anything about the differences between the 3 forms... so I just invented this name). How do you add a custom option to your form? It's something like this: There *is* a minor problem still: you will have duplicated HTML id's. If that's real problem, I think we could hack around it :).

    2) For how to handle the submit in the controller, can you tell me why you have 3 forms on the page? Will the user complete all 3 forms? Or will they only complete one of the forms based on some input?


  • 2018-01-16 Cesar

    Hi guys. I am using the form component and it is working really well. But now I need to render 3 times the "same" form in the same page. The only difference between those three are the options in the EntityType because it depends of what the user choose. Any suggestion that how I can do it? I don't want to duplicate code and I don't know how to manage different request in the controller. I hope you can oriented me.

  • 2017-10-05 weaverryan

    Nice work! And you're 100% right, these solutions are essentially the same - so thumbs up!

    And yea... learning stuff is hard... but I next time you'll be 100x faster. Keep going!


  • 2017-10-04 Ivan Loler

    hey weaverryan

    After more than 2 days of fighting with this, I finally figured it out on my own. Somewhere between my last comment and yours :'D

    The only difference is that I populated Movie object like this:

    $movie = new Movie();

    ... which is esentially the same :)
    The moment I figured it out, I almost started crying because of how easy the solution to my problem actually was and an amount of time I spent on it...
    Thanks anyway, keep going with your tutorials :)

  • 2017-10-04 weaverryan

    Yo Ivan Loler!

    I think you're quite close: you have correctly bound your form to your model class. I think the problem is entirely on your controller. Try this out: it's how I think the code should look, with some comments explaining :)


  • 2017-10-04 Ivan Loler

    Diego Aguiar

    Here are my pastebins:

    MoviePersonModel -
    MoviePersonForm -
    Controller -

    If my model and form are good, how can I persist specific fields to their associated Entities?
    The code in my controller is not working, because it creates an array, but I need an object to persist its values to certain table...

    Ryan says at the end of the video "'ll be your job to write a little bit of extra code that reads this data, updates your entities - or whatever else you need that data for - and saves things."
    That's what my question above is, what's that extra code I need?

  • 2017-10-03 Ivan Loler

    Hey Diego Aguiar

    Thanks for your time & response. I have tried first option, but it didn't work out well for me.
    Now I want to try the second one. How do I map all the fields in MoviePersonModel?

    Actually, could I contact you somehow more privately, because I would really like to solve this problem and understand it?
    Thanks in advance.

  • 2017-10-02 Diego Aguiar

    Hey Ivan Loler

    You can solve this by embedding FormTypes, you can create a new one which is a composition of a PersonFormType and MovieFormType, and it would need an extra field for the role type (director, actor, etc)
    Then, after submit, you can retrieve your objects something like this:

    // SomeController's action
    $data = $form->getData();
    $person = $data['person'] // or whatever is the name of the field

    You can find more information about embedding FormTypes in the docs:

    Another solution would be something similar as shown in the video. Creating a MoviePersonModel class (this is not an entity, because it won't be persisted in the DB), which will map all the fields you need from every other entity


  • 2017-10-02 Ivan Loler

    Hey Ryan, first, awesome tutorial!

    Second, on my project, I'm in a similar situation to the one you are mentioning at the end of this lecture (around 2:40).
    I don't know how to deal with it, so I would like to get your help & guidance, if possible.

    I have put my question on stackoverflow -

    Please, feel free to answer here or there.

  • 2017-08-28 Chris Rowden

    Hi, weaverryan and thanks so much for these tutorials. You guys are doing an amazing job and they are incredibly helpful! Hoping you can help me with an issue along the same lines as this question. I've definitely done my due diligence in researching the answer in, asking the question to Google in as many ways as i can think possible, which leads me to believe the answer is something obvious that I'm just missing, or I'm asking to do something that just isn't possible.

    Regarding this user's question - I have an entity "Customer Review" that I have a integer weight field on. The purpose is to allow site admins the ability to float certain reviews to the top based on the weight's field value - lesser numbers rise above greater values. This can all be successfully done in each singular entity. My desire is to create a page, however, where the weight of all customer reviews can be seen and edited all at once. Basically, the customer's name would be seen and right next to it would be that integer weight field that they could edit. My thought is that it would be much easier to adjust them all at once when you can visually see the entire order, especially if you had 20+ reviews! Hitting submit would then save all the entities with any new weights.

    I understand the technique that you're mentioning here in creating a new form class with just the fields needed and then applying them to the entity after isSubmitted() and isValid(), but I'm assuming this is meant more for a singular entity and not several at a time.

    My next thought is to utilize a CollectionType field, and I get the concept of using it to dynamically add/subtract fields of a certain type (like a collection of email fields), but for whatever reason, this still doesn't seem like what I'm trying to do, is it? I mean, I'm trying to edit (not add/subtract) a collection of entities, and with those entities, I'm really only wanting to edit one field - weight. I followed this tutorial and was able to successfully render a collection of weight fields on the page:

    If I create a new form class with just the weight field and set the data_class to the "Customer Review" Entity, is that the correct procedure? If so, I also have an file field in "Customer Review" that cannot be null (MySQL), and it's causing form validation to fail. With a new entity, it gets populated with a file with no problem, but on an edit page, the field is made optional - "if you like the photo you initially uploaded, just ignore or else upload a new photo to replace this one". Again, for a single entity, this is fine, I can make the field "not required".

    So, here are my questions - In the Stack Overflow answer, the user is passing an anonymous array of entities to createFormBuilder() and CollectionType > type (entry_type in 3.x) is set to a form class. Is this the right approach for what I'm trying to do, and if so, can you explain what arguments are supposed to be passed to createFormBuilder() and how this anonymous array is linking up with the form class in entry_type? Also, how do I pass an option to the collection of subforms indicating that the file field located on the data_class "Customer Review" (which is causing validation to fail) is in this situation optional (since it's already been set in a new entity creation action). And when it's all said and done, if I get validation to pass, is it just a matter of doing $this->getDoctrine()->getManager()->flush() in order to save all these entities in the database?

    Sorry if this is incredibly vague or confusing! I can certainly clarify anything if needed. My brain is just a bit mush from wrestling with this for far too many hours. Thanks!

  • 2017-06-23 Diego Aguiar

    Hey Richie Hamburg

    It's just a convention to follow, actually you can name your templates however you want, but that might get angry to other developers.


  • 2017-06-23 Richie Hamburg

    Does the underscore naming convention for includes() bring anything to the table?

  • 2017-05-05 Islam Elshobokshy

    Gosh I love these tutorials. How come I never knew about them before... D: In 2 days, I'm almost at the end (only the next course is left). Be proud of yourself. And be proud of what you're doing Ryan! I'll pass on the word about these tutorials.

  • 2017-02-07 Victor Bocharsky

    Hey James,

    Nice work! I'm glad you got it working! And thanks for sharing this - I just tweaked your message a bit to highlight the code blocks.

    P.S. You better don't use IDs for selecting elements like '#js-image-detail-preview' one - use CSS classes for this. ;)


  • 2017-02-07 Connect James

    Just a quick one as I found the solution to my problem, thanks to a var_dump($request->files->all()); as suggested I did a normal form in my template and the following in javascript:

    handleNewFormSubmit: function(e) {

    var $form = $(e.currentTarget);

    url: $form.attr('action'),
    type: 'POST',
    data: new FormData(e.currentTarget),
    processData: false,
    contentType: false
    }).success(function (data) {
    var place = '#js-image-detail-preview';

    var result = $(data);


    and the following in my controller:

    $uploadedFile = $request->files->all()['form']['image'];

    if (!$uploadedFile->isValid()) {
    // will by one of the constants like UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
    $error = $uploadedFile->getValue();


    // ...

    $fileName = md5(uniqid()) . '.' . $uploadedFile->guessExtension();

    // $cacheManager = $this->get('liip_imagine.cache.manager');
    // $cacheManager->remove('assets/images/products/tmp/' . $fileName);


    $pathImagePreview = 'assets/images/products/tmp/' . $fileName;

    All works perfectly now!

    Thanks again guys for all your help.

  • 2017-01-30 Victor Bocharsky

    Yo Connect,

    Yes, you're right! Check the latest released chapters on JavaScript for PHP Geeks - they were released a few days ago:


  • 2017-01-30 Connect James

    Is it something that would be available in the JavaScript for PHP Geeks sessions? I would really like to make it work with Ajax.



  • 2017-01-20 Connect James


  • 2017-01-19 weaverryan

    Hey James!

    I assumed you meant that you're not using a *Symfony* form. But you must at least use an HTML form... unless you're sending the file via AJAX or something fancy?


  • 2017-01-19 Connect James

    I do not use a form, I wanted to get the file without using the form. I explained it in the first comment.


  • 2017-01-19 weaverryan

    Hey James!

    Ok, let's see here. I agree with Victor in the first part! Probably just a forgotten enctype - I do this all the time :).

    Second, when you validate your image in this way, it is NOT using the validation rules from your entity - because your file object is never placed on it. In fact, let's back up a little bit - I see that you have an $image field on your entity, which will probably hold the filename of the file (this is perfect). But, if you were doing a bit more of a traditional, form-based upload, you would actually need a second, non-persisted field - e.g. imageFileObject - and *this* is where you would set the UploadedFile object into. And more importantly, THIS is where your @Assert constraints would go onto: it's the Uploaded file that you want to validate. But, you're not doing it that way (and totally fine - just wanted clear that part up). So, what I would do is (A) remove the validation constraints from your entity - as they simply won't be used - technically the NotBlank is ok, depending on your setup - as it would be a reminder to actually upload a file - but the Assert\File definitely won't work. Then, (B), validate manually in your controller:

    use Symfony\Component\Validator\Constraints\File;

    $constraint = new File();
    $constraint->mimeTypes = ["image/jpeg"];
    // btw, there is also an Image constraint, which is built to only accept images
    // $constraint = new Image(); // use statement is same as File, just end with \Image

    // now, use the validator service directly - this is basically what the form normally does for you
    $validator = $this->container->get('validator');
    $errors = $validator->validateValue($uploadedFile, [$constraint]);
    if (!empty($errors)) {
    // you have validator errors! You can loop over them to see the problem

    And finally, you're right that as long as you validate the incoming file as a jpeg, then you *should* be ok... though technically the user could still upload a valid jpeg... but have named it foo.exe, which is a little odd. It depends on how much you trust your users to not do weird things :).


  • 2017-01-19 Victor Bocharsky

    OK then, are you sending your form with POST method? Does you form has enctype="multipart/form-data"? Use "multipart/form-data" when your form includes any <input type="file"> elements. I bet the problem with enctype :)


  • 2017-01-19 Connect James

    Yes, array(0) { }, so I believe nothing.
    Twig code:
    <input type="file" name="myImage"/>
    Then a simple,
    <button id="save-all" type="button" class="btn btn-success">Save Product Changes</button>

  • 2017-01-19 Victor Bocharsky

    Hey Connect,

    Does your file's input HTML tag have the name attribute (like name="myImage")? Try to dump files to see what you receive:


    You need to find UploadedFile instance there.


  • 2017-01-19 Connect James

    I was sure it was that simple, I was really trying too hard.

    I tried the solution above and got the error below:
    Error: Call to a member function isValid() on a non-object
    It does not seem to want to take my picture when I request it, am I missing a "use" statement?
    I tried with very small files to be sure it was not php.ini the problem.

    And when you valid your file, is it taking the validation parameters from the product entity where the image is?

    Also you add a comment above the ->move saying "user could upload files with any extension" but is that not something I would check as part of my validation, ie:

    * @ORM\Column(type="string")
    * @Assert\NotBlank(message="Please, upload the product image as a .JPEG or .JPG.")
    * @Assert\File(mimeTypes={ "image/jpeg" })
    private $image;



  • 2017-01-16 weaverryan

    Hey James!

    So, you'd like to process a file upload, but *not* using the Form component, correct? No problem :). Suppose you have this:

    <input type="file" name="myImage"/>

    Then, in your controller, you can fetch it like this:

    public function editAction(Request $request)
    // an instance of UploadedFile
    $uploadedFile = $request->files->get('myImage');

    if (!$uploadedFile->isValid()) {
    // will by one of the constants like UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
    $error = $uploadedFile->getValue();

    // ...

    // note getClientOriginalName may not be safe to trust - user could upload files with any extension
    $uploadedFile->move('/some/dir', $uploadedFile->getClientOriginalName());

    Obviously, you could do a bit more with validation, etc - but this is the basic idea. Let me know if it helps!


  • 2017-01-13 Connect James

    Hi Ryan,
    I am creating an application and I need to upload an image.

    For the moment I did not used a form to get all the other inputs, and I would like to keep it like this, is there an easy way to have a simple file input field and get the file selected (image in my case) in my controller for editing and saving?

    Thanks a lot in advance

  • 2016-11-29 weaverryan

    Ha, nice job thinking correctly! Being able to think clearly about what objects you need and how they are related are the most important thing you can do to keep things clearly. So, keeping going! My advice to keep things simple would be:

    A) Build your model first (as you were already doing/describing) - make it as flexible as you need, but not more flexible :).

    B) If your Symfony form gets too complex, stop using it. Symfony forms are great, but eventually, if you need a lot of flexibility and user interaction, then you really need to build a normal HTML+JS frontend that adds/updates/deletes data via AJAX by hitting API endpoints in your app. Sometimes I see people build HUGE forms, with many embedded layers, which is both hard, and ultimately not a great user experience (i.e. because it means that your user does a lot of work, and none of it saves until they hit the save button at the bottom).

    Good luck Benjamin!

  • 2016-11-28 Benjamin Quarta

    Hey weaverryan,

    that are great news! I will go for the screencasts and let you if know how it worked out for me :)

    For the following part: Apologies if my english may be strange now and then, but since I'm no native speaker, I'll try to explain the best I can :D...

    To answer your question: The problem is much more complicated as it sounds, because in the finished version of the application the user should have *both* possibilities. Just imagine the use-case:
    A user is adding a new Publication, let's say it is an album holding 10 Songs (the table is called "tracks"). Now these song's exist in the table. Half a year later the third song of the album (let's call it "Ducktrinity" :P) is re-released on a compilation, Now the user that adds the compilation should have the possibility to either add a new song, which is then directly added to the song-table or select one existing song from the songs that already exist.
    But that is a problem which is "step 2", and I first want to get the simpler case of just "multiplying" forms going.

    Later on it is getting even more complicated:
    The application builds the groundwork of a netlabel-application, which means that we have to add lot's of meta-data, which an enduser does not really need, such as "ISRC" (International Standard Recording Code), which is kind of an EAN/UPC on the album-side, so that the track can uniquely be recognized as *this* song on *this* publication in the whole wide world.

    This said, you can imagine, that it's getting more complicated, when it comes to joining tables. It is technically the same song, but the ISRC will differ. If I just build a joining table and select the same song, i won't cover the issue in a clean way. If I - on the other hand - make a new entry for the same song twice, then i will have some redundancy in my database, which i am aiming to avoid.

    So my approach will be the following: Extending the "join tables". As I don't see by now that doctrine gives me the possibility to add additional fields to a join table (please tell me if I'm wrong) I need to make the join table a real table with an entity itself, so that we've got the following table-setup:
    - publication (which holds all the data for the publication itself)
    - join_publication_track (which holds the publication_id, the track_id PLUS ISRC and whatever else can differ)
    - track (which holds all the data for the tracks)

    EDIT: I just catched a glimpse at the Doctrine course (Chapter 16) and i see my approach seems pretty much like that, what you cover here :D... Guess I'm intuitively doing the thing right... good sign :P

    Before I'm running off the track (pun intended :P) even more, I'll stop at this point (since there is a lot more to do as relating tracks to each other... think of live-versions, radio-edits, instrumental-versions, etc. of the same track), but you get an idea where this leads ;)

    And thanks to Leanna, Victor and you it seems to be more fun than ever :) Keep up your great work!

    best regards :)

  • 2016-11-28 weaverryan

    Hey Benjamin Quarta!

    Nice to meet you - and I'm happy you're getting more and more dangerous :p.

    You've described your problem really well and you've setup your existing ManyToOne form setup perfectly. Well done :). And I have good news about your problem! We're covering it right now here: Specifically, you will be interested in the chapters 19-23. Now, the situation is *slightly* different, but all the information is there. What I mean is:

    A) In the tutorial, we first have a ManyToMany relationship. Here, we setup a form where the user checks checkboxes. In your app, this would be as if the user was simply *choosing* from existing "songs", not embedding a bunch of song forms.

    B) But later, we change to a "join table" setup (you'll see what I mean, it's chapter 16). Then, with this, we actually embed using the CollectionType.

    So, it sounds like you want to do what we do in part (B) from a form perspective, but with a ManyToMany relationship. I think if you go through those chapters, you'll have all the pieces you'll need (but you can ask here later if not).

    But, I have do have one question :). When the user is creating a new publication, are they choosing existing Songs from the database or creating new ones right then? If they're creating new ones, then perfect: you'll want the exact setup we're talking about here. But if you want the user to choose *existing* songs, then you'll actually want to follow the "checkboxes" setup instead... well... mostly. If you actually want the user to choose existing songs (instead of creating new ones), let me know and I'll give you more details.


  • 2016-11-27 Benjamin Quarta

    Hello there Ryan,

    thank you for the awesome courses, which make me feel "seriously dangerous" again :D...
    Okay... not as dangerous as I'd like to be by now, so I've got a question ;)

    To give it a context:
    Since we're talking of Symfony and this sound's a lot like music (and we all like listening to music, right?), I'd like to build an application, where you can store albums and artists

    I found out that, if I have another table "bound" to the entity-class (this is the job of doctrine), I simply can pass the other form to the first one like in my ArtistFormType... In the builder I simply can do the following:

    ->add('address', AddressFormType::class)

    and get the required fields in the Twig-template like that: {{ form_row(artistForm.address.street) }}

    This works just fine, but now I've got another challenge, which makes me a bit dizzy...

    Since the upper example is a ManyToOne-Relationship, I only have to pass the nested form once, and this is clearly addressable.
    But now, if I'm not storing Addresses but Album-Releases (which I'll call publications, because "release" is a reserved word), i have a ManyToMany Relationship, since many Releases can have many Songs (not OneToMany, since the song can appear on another publication, let's say a compilation too)...

    If I fill out a "New-Publication-Form" I should have the possibility to add a bunch of songs all at once, so the SongFormType must appear "multiple times" or - let's think of the User-Experience - there should be an "Add Song-Button" which dynamically repeats the Song-Form within the Release-Form...

    I really have no idea by now, how to approach that issue :D... Ryan and his team always have great ideas how to solve issues best practice... maybe you've got one for me ;)...

    Thanks in advance :)

  • 2016-10-18 weaverryan

    Sweet! I'm happy it's clear :). Your plan makes sense to me!

    Also, once User A edits the record, if you want to *force* them to fill in the missing fields, you can conditionally make those required by using NotBlank and validation groups: We do that in another tutorial to make some fields required on registration, but not required on a form that edits the user.

    Cheers and good luck!

  • 2016-10-18 Matt-You

    Hi there,

    Thank you for your answer! You are totally right, the problem comes from the database and it's that precise eror that I get. I knew that I could set it to "nullable=true" and allow another user (the admin for instance) to update the field (and set "@Assert\NotBlank" if I wanted the field to be updated anyway (the default value CANNOT be left like that). So, you made me think and came with this idea: I can set a default value that would be set automatically when the form creates a new entity. In my case, it's even better because it's more user-friendly. I explain myself: let's assume that user A is the admin and user B is a simple user of my platform. User B fills in the form (but he is allowed to fill only SOME fields, which are displayed). User A, then, edit the entity by completing the fields that user B were not allowed to do. Meanwhile, on a user B's page, I display the information that user B submitted and he/she waits for user A to "answer". So, it's better if by default, the field that user B couldn't fill in displays a value like "Waiting for user A to reply". And if I do that by default when the form is submitted, it's better both for my database and for my user B, C etc.

    All in all, just thank you very much for your answer! Everything is clearer now!

  • 2016-10-17 weaverryan

    Hey Matt!

    Thanks for the nice words man! And cool question - I have at least one answer for you, depending on your exact situation :).

    First, what you're doing is totally normal. In fact, it's really quite normal: it's really common to have a form that has some, but not all of your entity's fields mapped to it. When this happens, the *other* fields are just left completely untouched (i.e. if you're editing an entity, those fields will have the same value as when you fetched them from the database. If this is a new entity, they will remain null).

    In your situation, you say that you "get an error when submitting the form saying that I can't leave the field 'null'". From what you've told me, I assume that error is coming from the database - something like "Integrity constraint violation - Column cannot be null"? Is that accurate? If so, then I'm also guessing that this is a "new" form (not an edit form), otherwise this field would already be set in the database. And if *that's* true (I could be off-base by now), then the question is: how *should* this field be set? What I mean is, if the nullable=false property is not meant to be set in this form, but this form is creating a new entity that is meant to be inserted into the database, then we have a problem ... because nothing is ever setting this nullable=false field :).

    If I was right along my long line of assumptions, then you need to re-think this form: either that form should be nullable=true (because you *do* want it to be possible to create an entity from this form, but this user should not be able to set that value) *or* you'll need to set this value outside of the form (e.g. perhaps this user cannot edit this value, but that property should be given a default value, which you can do in the controller right before saving it).

    Or maybe I'm way off :). If so, let me know!


  • 2016-10-17 Matt-You

    Hi everyone,

    First of all, thanks for the tutorials which are remarkable!

    My question is about the end of the course, when you say that we should not bind our forms to our entities. Well, I think I have a problem related to that. I'll explain: I created a form that hydrates an entity, but only partially (I only use "->add()" on some fields). One of the attributes of my entity is set to "nullable=false" by default; this attribute is not part of my form because only one type of users can actually hydrate it (with a dfferent form). Nevertheless, I get an error when submitting the form, saying that I can't leave the field "null" whereas this very field is not in my form (I didn't use "->add()" on it).

    Basically, my question is: can we hydrate an entity partially through a form, even though one of the attributes is set to "nullable = false"?

    I hope I'm clear...
    Thanks in advance!

  • 2016-10-13 Johan

    Yea, they solved a lot of problems I had with Laravel. For example, one of them is having duplicated code in edit/create views. In a project these two views are often very similar, but not quite the same. One needs pre-filled fields, the other does not and validation requirements are slightly different. I was never able to find a really elegant solution for it in Laravel, but I think Symfony forms solved all those problems, it's beautiful :)

    Time to rewrite all my Laravel projects in Symfony! Haha!

  • 2016-10-13 weaverryan

    And forms can be tough in some cases... but they do SO much work for you. Anytime I try to use something like Silex without Symfony forms... I regret it quickly.

    Good luck and cheers!

  • 2016-10-11 Victor Bocharsky

    Hey Johan,

    Haha, well, Laravel uses a lot of Symfony components inside itself, so I think Symfony will be very familiar to you ;)
    Easy and interesting learning!


  • 2016-10-11 Johan

    I'm used to Laravel, but I think I just fell in love with Symfony <3

  • 2016-10-10 Victor Bocharsky

    OK, so speaking in terms, you have many-to-many relationship between Slide and Bank entities. Here's a link about this implementation using Doctrine ORM: . Is it appropriate for you?

    But with this approach, the SlideBank entity will be able to store only bank_id and slide_id. If you want to store a bit more information, like also a bank's name - you probably interested in a bit more complex relationships: Slide entity relates one-to-many to the SlideBank entity, which in turn relates many-to-one to the Bank entity, i.e. as a result you'll have the same many-to-many relationship between Bank and Slide, but you also will have ability to add more fields to the SlideBank entity except required bank_id and slide_id. This way you need 3 entities: Slide, Bank and SlideBank. I hope it makes sense for you.


  • 2016-10-10 diarselimi92

    Hey Victor Bocharsky thanks for your response, but i think i can't do that !

    i have a table where i have some banks in it but the problem is that i don't have to relate anything to that table i only have to get the banks and save them in another table that is related to the Slide Table

    the stucture : | BANK | i will get the data from this bank table, then i have | SLIDE | table where i will save the some slides here , then i have a table | SLIDE_BANK | where i will save every bank that i selected for a | SLIDE | here , so one SLIDE have multiple BANKS. note: I will not save the bank's id but the name in it.

    I hope it is understandable.
    I know how to do it in the PHP Way but i wan't to go by the symfony's rules.

  • 2016-10-10 Victor Bocharsky

    Hey diarselimi92 ,

    You can make relations first and then pass the new object to the createForm() as a second argument, i.e. build form on a object which already has relations with other objects. Look at the next example:

    // Use entity manager and repository to fetch any stored data from any tables
    $category = $em->getCategoryRepository()->find($categoryId);

    $post = new Post();
    // Make relations fetched data

    $form = $this->createForm(PostType::class, $post)
    // handle form...

    In the example above, the new Post object will be attached to the existent category.

    I hope I understand you right and this example helps you. Let me know if you still have any questions.


  • 2016-10-10 diarselimi92

    I was working on a form with symfony and i now wan't to save data to a table but i wan't to get the data from another table,
    ex: Table1 is where i wan't to save main data and i have Table2 related with Table1 but i wan't to get The data from Table3 and save those to Table2, does anyone had this issue and how could this be solved ?
    Thanks :)

  • 2016-09-12 Victor Bocharsky

    Ah, OK. So the correct way is pass the string value instead of array to the setter.

    The best practices is to use a "$plainPassword" property on User entity and add an event listener to encode the plain password to the password hash before update its value in DB. In the event listener you should encode plain password if only the $plainPassword property is NOT null. The only notice, that you should also change any mapped field of User entity, otherwise you will not get in the listener (it's because the $plainPassword is not mapped to the DB usually). So when you handle your form and set the new password to the $planPassword, you also should manually change $updatedAt field too (or any other mapped field, but usually, it's a $updatedAt field). It will be enough to trigger your event listener which in turn encode plain password and set its hash to the mapped $password property. But, first of all ensure you get the password inputed by user when handle the form.

    BTW, do you have any listeners which could update user entity after you? Check them all and ensure they do not update password field.

    P.S. You could see how to handle (encode) plain password with an entity listener in the next course Symfony Security: Beautiful Authentication, Powerful Authorization. Please, take a look at it.


  • 2016-09-12 james

    I already tried it also, same result:

    string(8) "password" NULL

    Which I really can't get it...

    $userPassword = $formForgotPassword->getData();


    $em = $this->getDoctrine()->getManager();



  • 2016-09-12 Victor Bocharsky

    Hey James,

    I think I see the problem ;). You dump $userPassword["plainPassword"] string value *but* then set $userPassword array to the user object. So try to change 3rd line to:



  • 2016-09-10 james


    Another question on another subject, I have my login form and register form, all good until I try to create the forgot password form. When the user click on forgot password, an email is sent to his email address with a link, the link has got his email address and a token created just before the email was sent. When the user clicks the link he is redirected to a page with a form to renew his password, same password part of the form than in the register form. But when the user enters the password and the repeat password (I changed the encoder to plaintext):


    $userPassword = $formForgotPassword->getData();



    $em = $this->getDoctrine()->getManager();






    "password" NULL

    What is the problem?

  • 2016-08-30 Victor Bocharsky

    Hey James,

    The second your example is correct. What does the quantities is? The second argument for path() Twig function should be an associative array, like {param1: 'value1', param2: 'value2'} if you declare your parameters in Twig. Try to set dummy data first and look if it works:

    {{ path('update_cart', {param1: 'value1', param2: 'value2'}) }}

    You should get some URL like this: "/your-update-cart-url?param1=value1&param2=value2", and then in action you can get access to these params via request:

    dump($request->query->get('param1')); // will dump "value1" string


  • 2016-08-30 james

    Thanks for the quick answer! I tried something like this:

    {{ path('update_cart', {quantities}) }}
    {{ path('update_cart', quantities) }}

    But it does not work, how do you insert the array as a parameter?

    Also when trying to get the value of the quantity input ( {{ dump(form.quantity.vars.value) }} ) it does seem to work...

  • 2016-08-30 Victor Bocharsky

    Hey James,

    Thanks to the Symfony Router component, it takes an array of parameters as a second argument, so you don't need to merge and encode your values, just pass your array as a second parameter to the "path()" or "url()" Twig functions and router do the job for you. If your route has some required parameters, then merge your parameters with it.


  • 2016-08-30 james


    Just a question concerning request of values form the twig template to a controller, is there any other way to get the values of twig template directly to our controller? I have for example a cart and a button to update the cart but form would not work because the quantity field will be included in each loop to get each product and so will appear as many time I have products. Any ideas?

    At the moment as a solution I am creating an array in twig, then merging elements to it, then encode it and add it to the url (/{{ items }}) and in my controller I can then decode the json and get my values. Complicated? maybe...

  • 2016-08-09 Victor Bocharsky


    Yes, Symfony plugin adds this method for backward compatibility, but you should avoid using it and since Symfony 2.8, the name defaults to the fully-qualified class name, i.e. Symfony generates this name for you behind the scene based on your FQCN. This class name is internal and used for generate unique form element names and CSS IDs. You could find it if inspect your form HTML code.


  • 2016-08-09 3amprogrammer

    Hey weaverryan!
    After watching this series I am a little confused about getName method. I was trying to find the moment when you have added this, but there is no one (or I've missed it). Can you please explain it to me briefly what is the purpose of:

    public function getName()
    return 'app_bundle_genus_form_type';

    I have found out that this method was added by Symfony Plugin. Anyway is there any reason for it?