symfony 4中的表单验证不起作用

时间:2018-09-29 13:12:02

标签: symfony symfony4

我创建了一个实体Testme,并使用bin/console make:crud生成了crud文件,并尝试向该表单添加验证规则,但是它不起作用:

我的实体:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="App\Repository\TestmeRepository")
 */
class Testme
{
 /**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @Assert\NotBlank()
 * @ORM\Column(type="string", length=255)
 */
private $name;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
private $description;

....

表格:

<?php

namespace App\Form;

use App\Entity\Testme;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TestmeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('description')
    ;
}

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

控制器动作:

/**
 * @Route("/{id}/edit", name="testme_edit", methods="GET|POST")
 */
public function edit(Request $request, Testme $testme): Response
{
    $form = $this->createForm(TestmeType::class, $testme);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $this->getDoctrine()->getManager()->flush();

        return $this->redirectToRoute('testme_edit', ['id' => $testme->getId()]);
    }

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

如果name字段为空,则在创建新实体时会正确显示验证错误,但是当我编辑它并清空name字段时,我得到一个InvalidArgumentException $form->handleRequest($request);行:

  

期望的类型为“字符串”,“ NULL”的参数。

我想念什么?

编辑:所有代码都是由make:Entitymake:crud命令生成的,我只在@Assert\NotBlank()属性上添加了$name

2 个答案:

答案 0 :(得分:4)

在任何验证之前 应用表格和发布的数据绑定。如果您提示设置器/加法器,则将在这种情况下运行。

在我的POV中,您不应为了满足第三方代码(此处为表单组件)而修改“模型”代码,因为这样可能会遇到诸如错误使用方法的问题(如果需要输入值,确保“非空”要求的唯一可能方法是避免接受空;一旦“忘记”在对象上调用valid,验证器本身将不执行任何操作,即使在这种情况下,您仍然拥有有效的可刷新对象。

相反,您应该将DTO或ValueObjects绑定到表单。这些对象可以接受您想要的任何类型的值(基本上是您期望的值,并且为null)。然后,您可以执行验证,例如,使用“命令”(不是DDD“概念”中的symfony,而是“命令”)可以填充并执行其他“数据传递”或对 real < / em>实体。

即使ste的答案将使其起作用,从概念上讲也是错误的,因为将您的代码暴露于此答案中上面解释的“域风险”。

答案 1 :(得分:1)

您应删除实体设置器中的类型提示,或将参数默认设置为null。

如果未更改字段(例如,在使用新对象的情况下),则表单组件可能不会更新字段(即调用setXXX)。

验证是在对象中完成的,因为在那里定义了约束(即@Assert批注)。

您可以使用约束直接在表单中进行验证。参见https://symfony.com/doc/current/form/without_class.html#adding-validation