如何在symfony2验证器中允许空值


How to allow empty values in symfony2 validators

我想只在value不为空时对对象属性应用验证器,例如

现在标准symfony行为:

class Entity
{
    /**
     * @ORM'Column(type="string", nullable=true)
     * @Assert'Email()
     */
    protected $email;
    (...)
}

对象将不通过验证,如果一个电子邮件是空的,或空字符串,有没有一种方法告诉验证器断言作为一个有效的,一个空值,并验证只有当字段有数据?

PS我知道我可以写回调验证器,但是为每个字段写回调只是为了有"allowEmpty"的特性是不太好。

必须在FormBuilder类中为所有可选字段显式设置'required' => false。下面是描述字段类型选项的段落。


编辑。得到相当多的反对票。默认情况下,所有验证器都将null值视为有效, NotNullNotEmpty除外。这两个词都没有出现在问题中。这个问题是关于如何关闭客户端默认打开的required属性的。

设置required选项不是解决办法:

还要注意,将所需选项设置为true将不会导致应用服务器端验证。换句话说,如果用户为该字段提交一个空白值(例如,使用旧浏览器或web服务),它将被接受为有效值,除非您使用Symfony的NotBlank或NotNull验证约束。

http://symfony.com/doc/current/book/forms.html field-type-options

对于我的自定义验证器,我添加了一个
if (null == $value) {
    return true;
}

isValid()方法。但是,我不确定标准验证器类的最佳方式是什么。

如果我理解正确,您希望服务器端验证仅当值输入。我的情况和你完全一样。我希望仅在提供URL时验证URL。我遇到的最好的方法是编写我自己的自定义验证类。您可以编写一个通用的自定义验证类。

我遵循这个链接https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html除了一些变化,因为symfony的最新版本。下面是

的实现

Acme ' ' BundleNameBundle '验证器'约束cstmUrl

namespace Acme'BundleNameBundle'Validator'Constraints;
use Symfony'Component'Validator'Constraint;
use Symfony'Component'Validator'Constraints'Url;
/**
 * @Annotation
 */
class CstmUrl extends Url
{
    public $message = 'The URL "%string%" is not valid';
}

Acme ' ' BundleNameBundle '验证器'约束cstmUrlValidator

namespace Acme'BundleNameBundle'Validator'Constraints;
use Symfony'Component'Validator'Constraint;
use Symfony'Component'Validator'Constraints'Url;
use Symfony'Component'Validator'Constraints'UrlValidator;
class CstmUrlValidator extends UrlValidator
{
    public function validate($value, Constraint $constraint)
    {
        if(!$value || empty($value))
            return true;
        parent::validate($value, $constraint);
    }
}

Validtion.yml

Acme'BundleNameBundle'Entity'Student:
    Url:
        - Acme'BundleNameBundle'Validator'Constraints'CstmUrl: ~

在控制器内部绑定你通常会做的约束

'constraints'=> new CstmUrl(array("message"=>"Invalid url provided"))

我相信会有其他更好的方法,但现在我觉得这样做很好。

以防其他人遇到同样的问题。我更喜欢通过在我的Twig模板中添加以下属性来解决这个问题:

{{ form_row(form.<field>, {'required': false}) }}

这是我发现的技巧:

https://github.com/symfony/symfony/issues/5906

您需要编写一个不执行任何操作的数据转换器,然后将其添加到字段中。之后,只需调用submit()方法,并将第二个参数设为false。

字段类型猜测处理此问题。http://symfony.com/doc/current/book/forms.html field-type-guessing

这取决于您的表单声明:"当您省略add()方法的第二个参数(或者如果您传递null给它)时,"猜测"将被激活。如果您将一个选项数组作为第三个参数传递(如上所述dueDate),这些选项将应用于猜测字段。"