Symfony2 验证器,NotBlank 但允许为空。

6
我在使用Symfony2验证器组件时遇到了问题,无法将值验证为允许NULL但不允许空字符串。我已经将该组件集成到Silex应用程序中,并使用Property Constraint目标来验证我的应用程序实体的一些属性(而不是Doctrine实体)。我在实体类中添加了这个静态方法来验证实体上的名称和service_id,问题是当service_id为NULL时,应该是有效的,但NotBlank约束会触发并报告违规。请帮忙看看怎么解决。
static public function loadValidatorMetadata(ClassMetadata $metadata)
{
    // name should never be NULL or a blank string
    $metadata->addPropertyConstraint('name', new Assert\NotNull());
    $metadata->addPropertyConstraint('name', new Assert\NotBlank());

    // service_id should either be a non-blank string or NULL
    $metadata->addPropertyConstraint('service_id', new Assert\NotBlank());
}

总之,我想知道如何允许一个字符串或NULL作为service_id,但不允许空字符串。

PS:我也尝试过MinLength(1)约束,但不幸的是它允许空字符串。


有一个 Null-Validator,但它也无法帮助你,因为只有 NULL 才是有效的,即使它是一个字符串(无论是否为空),它也会被违反。为什么不编写自定义验证器呢? - dbrumann
1
自定义验证器确实是一种选择,但对我来说,它似乎是一个常见的用例,很难相信它无法直接完成。 - ChrisR
我也是。实际上,这似乎是错误的(或者至少措辞不当)。对于我来说,NotBlank 意味着应该为空字符串进行验证。我不明白为什么约束将 null 视为空值。 - user986408
2个回答

12

如果您在以后的版本(从4.3开始)遇到此问题,您可以设置allowNull = true

namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class SomeEntity
{
    /**
     * @Assert\NotBlank(allowNull = true)
     */
    protected $someProperty;
}

9
NotBlank约束将null视为空值,可以在此测试中看到。

使用doctrine时,可以通过使用Valid约束来解决此问题。如果字段的值不是null,则会尝试对其进行验证。

由于您不是使用doctrine实体,因此可能需要使用回调验证器或编写自己的约束。

编辑

回答您关于将回调约束添加为属性约束的新问题:不,这是不可能的。

回调约束作用于整个对象,而不仅仅是单个属性。以下是如何使用回调约束的示例:

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\ExecutionContext;

$app = new Silex\Application();

$app->register(new Silex\Provider\ValidatorServiceProvider());

class Person
{
    public $name;

    public function validateName(ExecutionContext $context)
    {
        if ('John Doe' === $this->name) {
            $context->addViolationAtPath('name', 'Name must not be "John Doe"');
        }
    }

    static public function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addConstraint(new Assert\Callback(array('validateName')));
        $metadata->addPropertyConstraint('name', new Assert\NotNull());
    }
}

$person = new Person();
$person->name = 'John Doe';
$violations = $app['validator']->validate($person);
var_dump('Violations for John Doe');
var_dump((string) $violations);

$person = new Person();
$violations = $app['validator']->validate($person);
var_dump('Violations for Person with name null');
var_dump((string) $violations);

$person = new Person();
$person->name = 'Igor Wiedler';
$violations = $app['validator']->validate($person);
var_dump('Violations for Igor Wiedler');
var_dump((string) $violations);

从我尝试的来看,在Silex中回调验证器无法在属性约束上工作,或者我错了吗? - ChrisR
我已经更新了我的答案,以解释如何使用回调约束。 - igorw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接