【发布时间】: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) }}
几个兔子洞:
- 该站点在 localhost(Symfony、Apache、MySQL)上运行。
- 表单输入通过 POST 发送。
- 默认控制器在提交后重定向;添加了“退出”以暂停我的代码。
- 表单未嵌入。我已经缩减了整个项目,因为我认为嵌入式表单是问题所在。
- 我将方法更改为 PUT 并且可以看到附加到 URL 的表单值,但 $employer = $form->getData() 仍然使用空值填充 $employer。
- 我尝试在提交时使用 $form->get('companyName')->getData(); 获取单个表单字段;数据保持为空。
我不知道如何将表单数据保存到 Employer 对象。
【问题讨论】:
-
删除
->getForm中的buildForm。使用$form->handleRequest后,请勿使用$form->submit。不要使用dump($form),而是使用dump($employer)。表单默认为POST,无需检查。提交按钮通常添加在模板中({{ form_start(form) }}{{ form_widget(form) }}<button type="submit">submit</button>{{ 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