在不可为空的字段上验证 NotBlank

Posted

技术标签:

【中文标题】在不可为空的字段上验证 NotBlank【英文标题】:Validation NotBlank on a non nullable field 【发布时间】:2021-11-14 01:49:25 【问题描述】:

我正在尝试验证包含绝对不能为空或 null 的字段的表单。所以在我的模型中,它是这样定义的:

    /**
     * @var string
     */
    private $end;

    /**
     * @param string $end
     * @return Blabla
     */
    public function setEnd(string $end): Blabla
    
        $this->end = $end;
        return $this;
    

这是我表单中该字段的验证:

    $builder
        ->add('end', TextType::class, [
            'label'       => 'blabla',
            'constraints' => [
                new Length([
                    'min'        => 3,
                    'minMessage' => 'Min  limit  chars',
                ]),
                new NotBlank([
                    'message' => 'not null blabla',
                ]),
            ],
        ])

这是我在每个示例“多个空格”发送错误输入时收到的错误:Expected argument of type "string", "null" given at property path "end".

我可以通过在我的 setter 中添加接收 null 的可能性来纠正此错误

    /**
     * @var string|null
     */
    private $end;

    /**
     * @param string|null $end
     * @return blabla
     */
    public function setEnd(?string $end=null): blabla
    
        $this->end = $end;
        return $this;
    

但我发现允许字段接收 null 只是为了验证它并防止将字段设置为 null 值,这不是很连贯。

我们不能这样做吗?

【问题讨论】:

确保您的表单将正确的数据发送回控制器。我使用 API-Platform,遇到过几次类似的问题,例如,当我发现操作应该有一个像 someField 这样的属性时,我正在发送一个像 some_field 这样的属性。在这种情况下,我虽然发送了值,但由于拼写错误,Symfony 无法进行正确的验证。 【参考方案1】:

提交表单时,所有空值默认设置为null,因此您应该在设置器中接受null 或使用empty_data 自定义默认值:

型号:

    #[Assert\NotBlank]
    private string $end = ''; // Remember to initialise the field with empty string if you use typed properties

    public function setEnd(string $end): void
    
        $this->end = $end;
    

表格:

$builder->add('end', TextType::class, [
    'label' => 'blabla',
    'empty_data' => '',
]);

由于NotBlank 会检查空字符串,因此您仍然可以这样使用它。 这适用于某些内置字段,例如 TextType,但仍可能在其他字段中将空字符串转换为 null,因为 DataTransformers 也适用于 empty_data:docs

表单数据转换器仍将应用于 empty_data 值。这意味着空字符串将被强制转换为 null。如果您明确想要返回空字符串,请使用自定义数据转换器。

如果您想在表单类型中自定义 null 处理,请添加自定义 DataTransformer 或直接在表单类型中实现 DataTransformerInterface,就像在 TextType 中所做的那样:https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/Form/Extension/Core/Type/TextType.php

请注意,我使用了一些现代 PHP 功能(属性和类型化属性)来缩短代码。

【讨论】:

以上是关于在不可为空的字段上验证 NotBlank的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL - 用户友好的类型验证错误

iview表单验证一直提示为空的几个原因?

仅当字段不为空时才进行电子邮件验证

使用 Graphql 在 NestJS 上订阅时,“不能为不可为空的字段返回 null”

ASP.NET 核心模型验证无法按预期工作

必须初始化不可为空的实例字段“taskTitle”