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:Entity
和 make: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"。
我创建了一个实体 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:Entity
和 make: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"。