Validation 如何创建Symfony2.1验证约束以验证字符串中的令牌数

Validation 如何创建Symfony2.1验证约束以验证字符串中的令牌数,validation,symfony,token,symfony-2.1,Validation,Symfony,Token,Symfony 2.1,有时,值的集合作为唯一字符串存储在数据库中。此字符串由用户定义的分隔符(例如“,”或“389;”)分隔的所有值组成 在Symfony2.1应用程序中,最好有一个验证约束,通过计算字符串中包含的令牌数来验证字符串(例如,由输入文本表单提供) 一个可能的例子是,当您以字符串格式存储标记时,即您从输入字段接收字符串,如value1、value2、value10、value25。您可以看到传递了4个令牌,但没有表单验证器为您进行控制。因此,应该使用这样的验证器,如: /** * @Assert\Toke

有时,值的集合作为唯一字符串存储在数据库中。此字符串由用户定义的分隔符(例如“,”或“389;”)分隔的所有值组成

在Symfony2.1应用程序中,最好有一个验证约束,通过计算字符串中包含的令牌数来验证字符串(例如,由输入文本表单提供)

一个可能的例子是,当您以字符串格式存储标记时,即您从输入字段接收字符串,如
value1、value2、value10、value25
。您可以看到传递了4个令牌,但没有表单验证器为您进行控制。因此,应该使用这样的验证器,如:

/**
* @Assert\Token(
     *      delimiter=",", 
     *      min = "1",
     *      max = "5",
     *      minMessage = "You must specify at least one token",
     *      maxMessage = "You cannot specify more than 5 tokens")
*/ 
$tags;
在Symfony2.1中使用新的验证器时也有类似的情况,但它不适用于字符串,只适用于实现可计数的对象数组


谁知道如何实现这种“标记化字符串”验证器?

我解决了我的问题,我只想分享我的解决方案

一个可能的解决方案是使用一个新的解决方案。例如,按照问题中提供的标记列表示例:

/**
 * @Assert\Callback(methods={"isTagStringValid"})
 */
class AFormModel{

protected $tags;

    public function isTagStringValid(ExecutionContext $context){
        $tagsExploded = explode(',', $this->tags);

        if(count($tagsExploded)==0){
            $context->addViolationAtSubPath('tags', 'Insert at least a tag', array(), null);    
        }
        if(count($tagsExploded)==1 && $tagsExploded[0]==='')
            $context->addViolationAtSubPath('tags', 'Insert at least a tag', array(), null);            
        }
        else if(count($tagsExploded)>10){
            $context->addViolationAtSubPath('tags', 'Max 10 values', array(), null);            
        }
    }

}

更优雅的方法是定义“令牌”验证器。下面是一个例子:

namespace .....

use Symfony\Component\Validator\Constraint;

/**
  * @Annotation
*/
class Token extends Constraint {
    public $min;
    public $max;
    public $minMessage = '{{ min }} token(s) are expected';
    public $maxMessage = '{{ max }} token(s) are expected';
    public $invalidMessage = 'This value should be a string.';   
    public $delimiter = ',';
public function __construct($options = null){
    parent::__construct($options);

    if (null === $this->min && null === $this->max) {
        throw new MissingOptionsException('Either option "min" or "max" must be given for constraint ' . __CLASS__, array('min', 'max'));
    }
}    
}

验证程序类是:

namespace ...

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class TokenValidator extends ConstraintValidator {
    public function isValid($value, Constraint $constraint) {
        if ($value === null) {
            return;
        }
        if(!is_string($value)){
            $this->context->addViolation($constraint->invalidMessage, array(
                '{{ value }}' => $value,
            ));

            return;
        }

        $tokensExploded = explode($constraint->delimiter, $value);
        $tokens = count($tokensExploded);
        if($tokens==1){
            if($tokensExploded[0]==='')
                $tokens = 0;
        }

        if (null !== $constraint->max && $tokens > $constraint->max) {
            $this->context->addViolation($constraint->maxMessage, array(
                '{{ value }}' => $value,
                '{{ limit }}' => $constraint->max,
            ));

            return;
        }
        if (null !== $constraint->min && $tokens < $constraint->min) {
            $this->context->addViolation($constraint->minMessage, array(
                '{{ value }}' => $value,
                '{{ limit }}' => $constraint->min,
            ));
        }        
    }
}
名称空间。。。
使用Symfony\Component\Validator\Constraint;
使用Symfony\Component\Validator\ConstraintValidator;
类TokenValidator扩展ConstraintValidator{
公共函数有效($value,Constraint$Constraint){
如果($value==null){
返回;
}
如果(!是字符串($value)){
$this->context->addinvalition($constraint->invalidMessage,数组(
{{value}}=>$value,
));
返回;
}
$tokensExploded=explode($constraint->delimiter,$value);
$tokens=计数($tokensPloded);
如果($tokens==1){
如果($TokensPloded[0]='')
$tokens=0;
}
如果(null!=$constraint->max&&$tokens>$constraint->max){
$this->context->addinvalition($constraint->maxMessage,数组)(
{{value}}=>$value,
{{limit}}=>$constraint->max,
));
返回;
}
如果(null!=$constraint->min&&$tokens<$constraint->min){
$this->context->addinvalition($constraint->minMessage,数组)(
{{value}}=>$value,
{{limit}}=>$constraint->min,
));
}        
}
}
通过这种方式,您可以导入用户定义的验证器,并像我在问题中提出的那样在任何地方使用它