2012-04-13 75 views
4

我在驗證一個值時允許使用NULL,但沒有使用Symfony2驗證程序組件的空字符串。Symfony2驗證程序,NotBlank但允許爲空

我已將該組件集成到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()); 
} 

底線,我在尋找如何讓String或NULL作爲service_id但不允許空字符串。

PS:我也試過MinLength(1)約束,但不幸的是允許空字符串。

+0

有一個空值驗證,但它不會幫助你們,因爲只有NULL將是有效的,即如果它是一個字符串(空或不)它會被違反。爲什麼不寫一個定製的驗證器? – dbrumann 2012-04-13 12:57:06

+1

自定義驗證器確實是一種選擇,但對我來說,這似乎是一個常見的用例,很難相信它不可能做到開箱即用。 – ChrisR 2012-04-13 19:03:41

+0

我也是。事實上,這看起來甚至是錯誤的(或者至少是措辭)。對於我來說NotBlank意味着應該有一個空白字符串的驗證。我不明白爲什麼約束將null視爲空白值。 – codepushr 2014-05-14 19:27:44

回答

9

NotBlank約束將null視爲空白值,可以看到in this test

使用原則時,可以通過使用Valid約束來解決。如果該字段的值不是null,它將嘗試驗證它。

由於您沒有使用原則實體,您可能必須使用回調驗證器或編寫自己的約束。

編輯

要回答上添加一個回調約束作爲屬性約束新的問題:不,這是不可能做到這一點。

回調約束作用於整個對象,而不僅僅是一個屬性。這裏是你如何使用回調約束的例子:

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); 
+0

從我試過的回調驗證器不會在Silex的屬性約束或我錯了嗎? – ChrisR 2012-04-15 14:19:26

+0

我已經更新了我的答案,以解釋如何使用回調約束。 – igorw 2012-04-15 15:21:33