【问题标题】:Symfony form unchanged field returns validation type errorSymfony 表单未更改字段返回验证类型错误
【发布时间】:2019-06-24 10:38:35
【问题描述】:

尝试更新实体并提交值未更改的字段会导致类型错误。我做错了什么?

实体:

<?php

namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;
...
class User implements UserInterface
{
...

    /**
     * @ORM\Column(type="bigint", nullable=true)
     * @Groups({"default", "listing"})
     * @Assert\Type("integer")
     */
    private $recordQuota;

...

表单类型:

<?php

namespace App\Form;

...

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
...
            ->add('recordQuota', IntegerType::class)
        ;
    }

...
}

控制器:

...
    /**
     * @Route("/api/user/{id}", name="editUser")
     * @Method({"PUT", "PATCH"})
     * @Rest\View()
     */
    public function updateAction(Request $request, User $user)
    {
        $form = $this->createForm(UserType::class, $user);
        $data = $request->request->get('user');
        $clearMissing = $request->getMethod() != 'PATCH';

        $form->submit($data, $clearMissing);


        if ($form->isSubmitted() && $form->isValid()) {
...

我正在使用 PostMan 提交表单数据。 如果我正在更新的实体的 recordQuota 为 1000,我提交的表单具有不同的值。一切正常并更新。

但是,如果我使用 recordQuota: 1000 提交表单,这应该保持值不变,我会收到不正确的类型错误:

            "recordQuota": {
                "errors": [
                    "This value should be of type integer."
                ]
            }

附加信息:

我使用的是$form-&gt;submit 而不是handleRequest,因为我使用的是补丁。所以我需要能够启用/禁用$clearMissing。但即使使用handleRequest 也会产生同样的问题。

即使在将它传递给表单之前将 recordQuota 类型转换为 int 仍然失败。

如果我从表单和实体中删除所有类型信息,我会在实际进行更改时得到“此值应为字符串类型”。

【问题讨论】:

  • 和我自己的问题类似(stackoverflow.com/questions/56690952/…)。仍然没有解决方案。虽然,Assert 仅用于约束/检查/确认/验证,但它绝不会更改输入值的类型。
  • 所以,我已经尝试了您的代码,它实际上似乎工作正常——Type('integer')IntegerType 表单字段产生正确的结果(尽管在 HTML 表单环境中)。还有其他信息要分享吗?
  • 太糟糕了,我试图重现你的错误仍然失败——我的意思是,一切正常。我对 ATM 的所有想法都类似于远程调试,要求您这样做并复制粘贴,这似乎适得其反。没有更好的想法 ATM,对不起。
  • 请发布您的 getter/setter

标签: php symfony symfony-forms symfony-4.3


【解决方案1】:

编辑:请注意,如果字段类型为 TextType,则以下情况为真,但 IntegerType 可与 @Assert\Type("integer") 正常工作。这有点使我的答案无效/不相关......

你正在使用@Assert\Type("integer")注解,但这意味着:

  • value 必须是整数 -- 作为 PHP 类型,就像调用 is_int($value)
  • 并且由于数据来自表单(并且可能没有任何转换器,正如我在您的代码中看到的那样),它的类型是string
  • 因此,验证总是失败

你需要的是@Assert\Type("numeric"):

  • 相当于is_numeric($value)
  • 当它到达实体的字段时,它将被转换为字符串

【讨论】:

    【解决方案2】:

    这是一个组合 Symfony 4.3 验证器 auto_mapping 描述的问题: https://symfony.com/blog/new-in-symfony-4-3-automatic-validation

    并且制造商捆绑将错误的类型转换添加到 bigint 字段。

    请看这里: https://github.com/symfony/maker-bundle/issues/429

    答案是将实体中的 getter 和 setter 更改为:

        public function getRecordQuota(): ?int
        {
            return $this->recordQuota;
        }
    
        public function setRecordQuota(?int $recordQuota): self
        {
            $this->recordQuota = $recordQuota;
    
            return $this;
        }
    

        public function getRecordQuota(): ?string
        {
            return $this->recordQuota;
        }
    
        public function setRecordQuota(?string $recordQuota): self
        {
            $this->recordQuota = $recordQuota;
    
            return $this;
        }
    

    或者,可以在验证器配置中关闭 auto_mapping。

    【讨论】:

      猜你喜欢
      • 2015-05-02
      • 1970-01-01
      • 2021-01-01
      • 2015-01-16
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多