Validation 如何创建Symfony2.1验证约束以验证字符串中的令牌数
有时,值的集合作为唯一字符串存储在数据库中。此字符串由用户定义的分隔符(例如“,”或“389;”)分隔的所有值组成 在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
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,
));
}
}
}
通过这种方式,您可以导入用户定义的验证器,并像我在问题中提出的那样在任何地方使用它