【问题标题】:Symfony 5.1 $form->getData() Always Null (Basic Form)Symfony 5.1 $form->getData() 始终为空(基本形式)
【发布时间】:2020-07-09 05:57:55
【问题描述】:

这个 Symfony 表单问题已经被问了 100 次(我已经阅读了所有的回复),但没有一个对我有用。我有一个类(Employer)、一个表单(Preview.html.twig)和一个控制器(DefaultController.php)。无论我尝试什么,我仍然会得到表单字段的空值。表单显示正确,我没有保存到数据库(我只想转储变量,然后我将继续进行 db 操作)。这花费了我数周的时间,真诚感谢任何帮助。

默认控制器 (DefaultController.php)

<?
    namespace App\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    use App\Entity\Employer;
    use App\Form\EmployerType;


 class DefaultController extends AbstractController
 {  /**
    * @Route("/preview", name="preview")
    */
    public function preview(Request $request)
       {  
          $employer = new Employer();
    
          $form = $this->createForm(EmployerType::class, $employer, ['csrf_protection' => false]);
    
          $form->handleRequest($request);
    
          //the next two lines were added to force the form to submit, which it wasn't doing prior to
          if ($request->isMethod('POST')) {
            $form->submit($request->request->get($form->getName()));
            
            if ($form->isSubmitted() && $form->isValid()) {
    
                  $employer = $form->getData();
                  dump($form);     /****** ALL ENTRIES FROM THIS DUMP ARE NULL. *****/
                  exit;            /***Added to capture dump ******/
                  return $this->redirectToRoute('homepage');  /** Works when the exit is removed ***/
                }
              }

              return $this->render('preview.html.twig',
                                    ['form'=> $form->createView()]
                                  );
    }}

雇主类 (Employer.php)

namespace App\Entity;

class Employer
{
  protected $companyName;
  protected $companyAddress;

  public function setCompanyName($companyName)
  { $this->companyName = trim($companyName); }

  public function getCompanyName()
  { return $this->companyName; }

  public function setCompanyAddress($companyAddress)
  { $this->companyAddress = trim($companyAddress); }

  public function getCompanyAddress()
  { return $this->companyAddress; }
}

表单生成器(EmployerType.php)

<?php

namespace App\Form;

use App\Entity\Employer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class EmployerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    { 
        $builder
            ->add('companyName', TextType::class, ['label' => 'Company Name', 'required' => false])
            ->add('companyAddress', TextType::class, ['label' => 'Address', 'required' => false])
            ->add('submit',SubmitType::class, ['label' => 'Submit & Preview'])
            ->getForm()   //I've added and removed this line multiple times. Not sure if its needed.
          ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Employer::class,
        ]);
    }
}

用于显示 (Preview.html.twig) ** 正确显示表单 **

{{ form(form) }}

几个兔子洞:

  1. 该站点在 localhost(Symfony、Apache、MySQL)上运行。
  2. 表单输入通过 POST 发送。
  3. 默认控制器在提交后重定向;添加了“退出”以暂停我的代码。
  4. 表单未嵌入。我已经缩减了整个项目,因为我认为嵌入式表单是问题所在。
  5. 我将方法更改为 PUT 并且可以看到附加到 URL 的表单值,但 $employer = $form->getData() 仍然使用空值填充 $employer。
  6. 我尝试在提交时使用 $form->get('companyName')->getData(); 获取单个表单字段;数据保持为空。

我不知道如何将表单数据保存到 Employer 对象。

【问题讨论】:

  • 删除-&gt;getForm 中的buildForm。使用$form-&gt;handleRequest 后,请勿使用$form-&gt;submit。不要使用dump($form),而是使用dump($employer)。表单默认为POST,无需检查。提交按钮通常添加在模板中({{ form_start(form) }}{{ form_widget(form) }}&lt;button type="submit"&gt;submit&lt;/button&gt;{{ form_end(form) }}),无需将其添加到您的表单中(可重用性)。最后一个是可选的。
  • 感谢您抽出宝贵时间回复。我按照建议对模板进行了更改,以更好地控制表单。我还在 buildForm 中删除了 ->getForm。另一个建议(在使用 $form->handleRequest 后不要使用 $form->submit),只会导致表单在页面上重新加载而根本没有被处理。我正在使用 $form->submit 来强制表单的手。我什至将方法更改为 PUT 并使用 if ($request->isMethod('PUT')).... 仍然将 null 值加载到雇主中(我转储而不是表单)。
  • 将方法更改为 PUT 很可能会导致问题。你是怎么做的,在哪里做的,请告诉我们。当你使用 PUT 时,$request->request->get() 可能是错误的,不太确定,因为我几乎从不使用 PUT。 (这确实是错误的方法,在developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT 中明确表示:HTML 表单中允许:否)。我给出的评论/建议实际上是针对您提供的代码,因为很难为未提供的代码提供代码建议。如果您将其应用于给定的代码,它应该工作。

标签: forms apache symfony null submit


【解决方案1】:

您必须删除EmployeType 中的getForm()。 在 DefaultController 中,删除包含 form-&gt;submit() 的行。在这里,您初始化的员工是自动填写的表格。要检索您的员工,您不再需要执行 $form-&gt;getData()。员工已经满了。您可以使用dd($employer) 而不是$employer = $form-&gt;getData() 进行检查

【讨论】:

    【解决方案2】:

    我放弃并使用 Composer 创建了一个新的 Symfony 实例。重新开始让我想到了这个问题。我的自定义树枝文件中的某些东西(我还不确定是什么)导致了问题。等我弄明白了会更新大家的。

    最终发现: 我的表单输入的名称属性不正确。控制器期望命名输入格式为:

    formName[formField] //Ex: employer[companyName]
    

    而我的是 Twig (formName_formField) 生成的标准类型

    添加:

     <p>form.vars: </p>
        {{ dump(form.vars) }}
    

    在我的 Twig 文件中,我找到了答案。我使用自定义表单主题修改了输入,首先将以下行添加到 twig.yaml:

    form_themes: ['custom_bootstrap.html.twig']
    

    然后,在自定义文件中,我为用于覆盖默认值的每种输入类型创建了一个新实例。例如,对于复选框,我的代码是:

    {% use "form_div_layout.html.twig" %}
    
    {%- block checkbox_widget -%}
        <input type="checkbox" id="{{ form.vars.name }}" name="{{ full_name }}"
          {%- if disabled %} disabled="disabled"{% endif -%}
          {%- if required %} required="required"{% endif -%}
          {% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %}
          {{ block('attributes') }}
        />
    {%- endblock checkbox_widget -%}
    

    您应该能够直接将名称值添加到您的树枝模板中,而无需使用自定义文件。我真的希望这可以帮助某人节省时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-15
      • 2018-02-02
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 2023-03-11
      • 2020-03-19
      相关资源
      最近更新 更多