如何使用Symfony验证验证数组键?
说我有以下,电子邮件数组的每个键都是一个ID.如何使用回调或其他一些约束来验证它们(例如,正则表达式约束而不是回调)?
$input = [
'emails' => [
7 => 'david@panmedia.co.nz',12 => 'some@email.add',],'user' => 'bob','amount' => 7,];
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints;
$validator = Validation::createValidator();
$constraint = new Constraints\Collection(array(
'emails' => new Constraints\All(array(
new Constraints\Email(),)),'user' => new Constraints\Regex('/[a-z]/i'),'amount' => new Constraints\Range(['min' => 5,'max' => 10]),));
$violations = $validator->validateValue($input,$constraint);
echo $violations;
(使用最新的dev-master symfony)
我将创建一个自定义验证约束,该约束对数组中的每个键 – 值对(或键只需要)应用约束.与“所有”约束类似,但是对键值对执行验证,而不是仅对值进行验证.
namespace GLS\DemoBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\ConstraintDeFinitionException;
class AssocAll extends Constraint
{
public $constraints = array();
public function __construct($options = null)
{
parent::__construct($options);
if (! is_array($this->constraints)) {
$this->constraints = array($this->constraints);
}
foreach ($this->constraints as $constraint) {
if (!$constraint instanceof Constraint) {
throw new ConstraintDeFinitionException('The value ' . $constraint . ' is not an instance of Constraint in constraint ' . __CLASS__);
}
}
}
public function getDefaultOption()
{
return 'constraints';
}
public function getrequiredOptions()
{
return array('constraints');
}
}
约束验证器,其将带有键值对的数组传递给每个约束:
namespace GLS\DemooBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class AssocAllValidator extends ConstraintValidator
{
public function validate($value,Constraint $constraint)
{
if (null === $value) {
return;
}
if (!is_array($value) && !$value instanceof \Traversable) {
throw new UnexpectedTypeException($value,'array or Traversable');
}
$walker = $this->context->getGraphWalker();
$group = $this->context->getGroup();
$propertyPath = $this->context->getPropertyPath();
foreach ($value as $key => $element) {
foreach ($constraint->constraints as $constr) {
$walker->walkConstraint($constr,array($key,$element),$group,$propertyPath.'['.$key.']');
}
}
}
}
我猜,只有回调约束适用于每个键值对,在那里你放置验证逻辑.
use GLS\DemoBundle\Validator\Constraints\AssocAll;
$validator = Validation::createValidator();
$constraint = new Constraints\Collection(array(
'emails' => new AssocAll(array(
new Constraints\Callback(array(
'methods' => array(function($item,ExecutionContext $context) {
$key = $item[0];
$value = $item[1];
//your validation logic goes here
//...
}
))),'user' => new Constraints\Regex('/^[a-z]+$/i'),$constraint);
var_dump($violations);