Buy
Buy
This tutorial has a new version, check it out!

Inspect the HTML and check out the <form> element. Notice: this does not have an action attribute. This means that the form will submit right back to the same route and controller that renders it. You can totally change this, but we won't.

In other words, our single action method will be responsible for rendering the form and processing it when the request method is POST.

Before we do any processing, we need the request. Type-hint it as an argument:

... lines 1 - 7
use Symfony\Component\HttpFoundation\Request;
... lines 9 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
... lines 34 - 44
}
}

$form->handleRequest()

Next, to actually handle the submit, call $form->handleRequest() and pass it the $request object:

... lines 1 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
$form = $this->createForm(GenusFormType::class);
// only handles data on POST
$form->handleRequest($request);
... lines 38 - 44
}
}

This is really cool: the $form knows what fields it has on it. So $form->handleRequest() goes out and grabs the post data off of the $request object for those specific fields and processes them.

The confusing thing is that this only does this for POST requests. If this is a GET request - like the user simply navigated to the form - the handleRequest() method does nothing and our form renders just like it did before.

Tip

You can configure the form to submit on GET requests if you want. This is useful for search forms

But if the form was just submitted, then we'll want to do something with that information, like save a new Genus to the database. Add an if statement: if ($form->isSubmitted() && $form->isValid()):

... lines 1 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
$form = $this->createForm(GenusFormType::class);
// only handles data on POST
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
... line 39
}
... lines 41 - 44
}
}

In other words, if this is a POST request and if the form passed all validation. We'll add validation soon.

Fetching $form->getData()

If we get inside this if statement, life is good. For now, just dump the submitted data: dump($form->getData()) and then die;:

... lines 1 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
$form = $this->createForm(GenusFormType::class);
// only handles data on POST
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($form->getData());die;
}
... lines 41 - 44
}
}

OK, let's see what this dumps out!

Fill out the form with very realistic data and submit. Check that out! It dumps and associative array with the three fields we added to the form. That's so simple! We added 3 fields to the form, rendered them in a template, and got those three values as an associative array.

Now, it would be very, very easy to use that associative array to create a new Genus object, populate it with the data, and save it via Doctrine.

But, it would be awesomesauce if the form framework could do our job for us. I mean, use the data to automatically create the Genus object, populate it, and return that to us. Let's do that.

Leave a comment!

  • 2018-11-16 Victor Bocharsky

    Hey Cryptoblob,

    Yeah, sometimes upgrade to a new minor version is not simple, but Symfony do their best to make it smooth. You can take a look at UPGRADE-3.*.md files here: https://github.com/symfony/... . So, if you want to upgrade from Symfony 3.1 to 3.4 - take a look at UPGRADE-3.2.md, UPGRADE-3.3.md and UPGRADE-3.4.md files. They contain some instuctions you have to do in order to upgrade Symfony packages. Though, if there're other dependencies in your project, you need to look at their changelogs to know what exactly actions they require from you.

    I hope this helps!

    Cheers!

  • 2018-11-16 Victor Bocharsky

    Hey Cryptoblob,

    It sounds like a BC breaks in a your current PHP version. SO, I think you just need to upgrade dependencies, probably Symfony validator at least. I think if you run this code on a lower PHP version - it should work without this warning, but would be better to upgrade that dependency. I bet this problem was already fixed in a newer version.

    Cheers!

  • 2018-11-15 Cryptoblob

    i upgraded symfony to 3.4 that broke everything, so i downgraded back to 3.1. Now everything works.... very weird haha

  • 2018-11-15 Cryptoblob

    Im getting a weird error in a file I haven't even touched...

    Warning: count(): Parameter must be an array or an object that implements Countable

    in vendor\symfony\symfony\src\Symfony\Component\Validator\Validator\RecursiveContextualValidator.php at line 712

    what???

  • 2018-03-09 Eddy

    yooo, you were right ! I upgraded symfony to version 3.4 and its working now.
    Tnx a lot !
    Cheers ! :)

  • 2018-03-09 Eddy

    Hey Diego,

    My version is : Symfony version 3.0.9
    Cheers!:D

  • 2018-03-08 Diego Aguiar

    Hey @Eddy

    Your form looks good to me, so I believe this is an incompatability with an older Symfony version and PHP7
    Can you tell me which Symfony version are you using?
    Maybe if you upgrade to a newer version it will be fixed

    Cheers!

  • 2018-03-07 Eddy

    Hey,

    Here is my part of code
    https://gist.github.com/edd...
    Maybe this can help. :)

    Cheers!

  • 2018-02-07 weaverryan

    Hey Eddy!

    Bah, nice find with the BrowserKit Request! Indeed, everything would blow up immediately when you added that!

    About your new error.... hmm, tricky! It *might* be a PHP error - it's certainly "weird" enough. The error comes from here: https://github.com/symfony/... - and I don't see any change to this line in newer versions of Symfony (so, if it were a PHP bug, we would have fixed it by now!).

    Can you post your form and controller data? And also, a screenshot of the stacktrace? The error is odd, because that line of code checks to make sure the value is an array or Countable!

    Cheers!

  • 2018-02-05 Eddy

    I am using php 7.1 :D

  • 2018-02-05 Eddy

    Heya,

    I got an answer which was resolution for my issue.
    Problem was that i passed Symfony\Component\BrowserKit instead \Symfony\Component\HttpFoundation\Request as param to my method in controller which was wrong.
    Now i have another problem, after i submit form, which might be related to php version.

    Warning: count(): Parameter must be an array or an object that implements Countable
    vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 716

    So, if some of you have resolution for this as well , i would be really really nice :D :D
    TNX! ;)

  • 2018-02-05 weaverryan

    Hey Eddy!

    Ah, I just saw your other note about this and asked you to make a comment. I see you already did - excellent!

    I'm not sure I fully understand the problem yet. You said:

    > It seems that adding Request and $form->handleRequest($request) is valid just after i submit form.

    Can you explain that in more detail? Do you get an error when you render (don't submit) the form? Or do you not have an error, but a difference problem?

    Let us know - sorry I couldn't quite understand the issue yet - but we'll get to the bottom of it!

    Cheers!

  • 2018-02-04 Eddy

    Hi guys,

    I have problem rendering form after i added Request object as argument in newAction method.
    It seems that adding Request and $form->handleRequest($request) is valid just after i submit form.
    And i can not find solution in downloaded script because there is no proper code according to this part of course.
    Do you know how can i solve this issue ?

    Cheers ! :D

  • 2018-02-01 Victor Bocharsky

    You're welcome, and happy learning! ;)

    Cheers!

  • 2018-01-31 Tom

    Hey Victor,

    Thanks a lot for your reply. I will do that then.

    Thanks again for the good work !

    Tom.

  • 2018-01-30 Victor Bocharsky

    Hey Tom,

    Welcome! And that's a good question! Well, you definitely need to start with Symfony Flex, and the only tutorials about it is in Symfony 4 track. So I'd say you better start with Symfony 4. Then, when you finish all the Symfony 4 courses, you can start watching Symfony 3 related courses because we have a lot of topics covered there. But now, since you already know how to use Symfony Flex, instead of doing it in Symfony 3 way you should use Flex.

    Cheers!

  • 2018-01-29 Tom

    Hey,

    I'm new with Symfony. I was just wondering... Should i start directly to learn Symfony4 or should i come back a little and go with Symfony 3 since there are so much more tutorial about it ?

    Thanks a lot, i really enjoy your tutorials.

    Cheers from France.

  • 2017-11-20 weaverryan

    Yo mattxtlm!

    Ah, you're really close! There is one... maybe two problems :)

    1) Remove $form->handleRequest(). That's redundant: you're actually submitting your form *two* times - once with submit() and again with handleRequest, but with empty data. When you call handleRequest(), it finds the fields on the POST data, and then *it* calls submit() internally. So, remove that line!

    2) I believe for the myDate value, you will need something different. When you use submit, you should submit the data in the format that would normally come from the web. So, it would actually be:


    $form->submit(['myDate' => [
    'year' => 2017,
    'month' => 11,
    'day' => 20
    ]]);

    It needs this format because, by default, the DateType field renders as 3 select elements, calls year, month & day. If you set the widget option on that field to single_text, then it would render as a single input text. So, you would submit text:


    $form->submit(['myDate' => '2017-11-20']);

    I hope that helps! Cheers!

  • 2017-11-16 mattxtlm

    Hey,

    I played around with submitting the form manually. That works great. But I get stuck at submitting a form with a DateType-Field.


    $form = $this->createFormBuilder()
    ->add('myDate',DateType::class)
    ->add('submit',SubmitType::class)
    ->getForm();

    $form->submit('myDate' => new \DateTime());
    $form->handleRequest($request);

    if($form->isSubmitted()) {
    dump($form->getData()); // will return []
    }

    Do I miss something?

    Thanks.

  • 2017-07-12 Victor Bocharsky

    Hey Terry,

    Thanks for this notice! You're totally right now. You came across an old comment which was left more than year ago, but now situation is changed.

    Cheers!

  • 2017-07-11 Terry Caliendo

    But according to the docs it looks like in future versions isValid() will throw an exception if its not submitted, so it will cause issues upon upgrade, won't it?:
    http://api.symfony.com/3.3/...

    If the form is not submitted, this method always returns false (but will throw an exception in 4.0).

    .
    .

  • 2017-06-12 Diego Aguiar

    Hey maxii123

    That's because you explicitly specified to use "GET" method on your form, by default it uses "POST", and you should use it too, because it's more secure, and it's an standard when you are creating records on your system

    Cheers!

  • 2017-06-10 maxii123

    I need some clarification about you saying it only handles POST data. This code of mine populates the form object from a GET query just fine. What am I mixing up? ie when I render the form it still contains the submitted values (this is a search dialog). https://gist.github.com/ril...

  • 2016-08-08 weaverryan

    Definitely! I also leave off isSubmitted() in practice - it's nice to show to beginners at first, but I'm too lazy to include it after ;).

    Thanks for the note!

  • 2016-08-08 3amprogrammer

    Checking if form is valid is totally fine, as isValid checks for isSubmitted also :)

  • 2016-07-13 Carlo Mario Chierotti

    Thank you Victor!

    Carlo

  • 2016-07-13 Victor Bocharsky

    Hey Carlo!

    Good catch! BTW, you should move the session save path to a directory that is not shared between host and guest machines in case you want to use "handler_id: session.handler.native_file". For more information please check this issue.

    Cheers!

  • 2016-07-13 Carlo Mario Chierotti

    Hello Ryan,

    I followed your advice I was NOT able to retrieve the value from the session.

    I checked ALL the differences between my code and your code and I found this difference in config.yml:

    YOURS
    session:
    handler_id: ~

    MINE
    session:
    handler_id: session.handler.native_file

    I updated my config.yml and BOOM: problem solved.

    I am using a standard Debian Jessie VM in Vagrant, I don't know why the standard setup doesn't work.

    thank you for your help!

    Carlo

  • 2016-07-12 weaverryan

    Hey Carlos!

    Hmm - this doesn't sound good at all :). Victor was right - basically the *only* way you can mess this up is by forgetting to render the field (which you haven't done!). I've only seen CSRF tokens fail *one* other time ever, and it was when someone had misconfigured their session storage (which is not something you normally need to configure at all). CSRF tokens work via your session - so this is *possibly* the problem.

    Here's how you can see if your session is working.

    1) Find your favorite controller and add the following:


    $this->get('session')->set('testing_value', 'yay');

    2) Go to the URL that executes this controller

    3) Update the code in your controller


    // $this->get('session')->set('testing_value', 'yay');
    dump($this->get('session')->get('testing_value'));die;

    4) Go back to that URL. Were we able to load the value from the session?

    Cheers!

  • 2016-07-11 Carlo Mario Chierotti

    hello Victor,

    I checked the source of the page and I confirm my form has the hidden field with the token.

    when I submit the form and I check in the profiler the POST parameters, the _token value is the same as the value I saw in the form, but I still get the error message about the CSRF token.

    thank you for your help.

    carlo

  • 2016-07-11 Victor Bocharsky

    Hey Carlo Mario Chierotti ,

    How does your form look like? Probably, you forget to render a SCRF hidden field. Actually, you don't need to render it manually, Symfony does it behind the scene when {{ form_end(form) }} is called. Do you have a `form_end` call on your page? If so, just open this form page in your browser to regenerate SCRF token and submit this form again.

    Cheers!

  • 2016-07-08 Carlo Mario Chierotti

    Hello,

    let me say your tutorials are really awesome!

    I have a question for you. when I try to dump the data with

    dump($form->getData());

    it get this warning:

    The CSRF token is invalid. Please try to resubmit the form.

    I double checked the code but the error remains the same. can you please help me?

    thank you!

    carlo