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

Form validation in symfony 4 doesn't work

我创建了一个实体 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); 行:

Expected argument of type "string", "NULL" given.

我错过了什么?

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

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

也许表单组件不会更新字段(即调用 setXXX),如果它们没有改变(就像在新对象的情况下)。

验证是在对象中完成的,因为您的约束(即@Assert 注释)在此处定义。

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

在任何验证之前应用表单和发布的数据绑定。如果您键入提示 setters/adders,您将在这种情况下 运行。

根据我的观点,您不应修改 "model" 代码以满足第三方代码(表单组件,此处),因为您可以 运行 解决可能的问题,例如错误使用方法 (如果需要一个值,确保 "not null" 要求的唯一可能方法是避免接受 null;一旦您 "forget" 在对象,即使在那种情况下,您仍然有一个有效的 可刷新对象)。

相反,您应该将 DTO 或 ValueObject 绑定到您的表单。这些对象可以接受您想要的任何类型的值(基本上是您期望的值和 null)。然后你可以执行验证,例如,使用 "command"(不是 symfony,DDD "concept" 中的 "command")你可以填充并执行其他 "data passage" 或操纵 真实 个实体。

即使 ste 的回答能让它工作,但在概念上是错误的,因为将您的代码暴露给上面在这个答案中解释的 "domain risks"。