使用Symfony Validation组件根据给定数组内的键来验证特定的数组结构

时间:2019-04-23 07:28:07

标签: php symfony

给出以下数组:

$a = [
    ['type' => 'foo', 'abc' => 'whatever'],
    ['type' => 'bar', 'xyz' => 'whatever'],
];

我想使用Symfony验证组件来验证$a$a的类型应该是array,并且其中的每个元素都应该是数组,并且应符合以下两个规则之一:

  • 如果元素的键"type""foo",则要求键"abc"
  • 如果元素的键"type""bar",则要求键"xyz"

我试图将All约束与Collection约束一起使用以指定字段,但这并没有完成,因为它基本上迫使我同时制作"abc"和{ {1}}可选。

人们将如何验证这一点?

1 个答案:

答案 0 :(得分:-1)

您正在使用哪个版本的symfony?

我建议您创建自己的验证约束以完成任务。

为此,您需要创建并扩展两个类。

  • 一个Constraint,将用于命名约束并使用它。
  • 将执行验证的ConstraintValidator

两个类都应该在同一个命名空间中。

约束的示例可能是:

namespace FooBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class ArrayStructure extends Constraint
{
    public $message = "The array structure is invalid";
}

验证器中将使用“ message”属性来显示错误消息。*

ConstraintValidator 可能是:

namespace FooBundle\Validator\Constraints;

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

class ArrayStructureValidator extends ConstraintValidator
{
    public function validate($array, Constraint $constraint)
    {
        if (!$constraint instanceof ArrayStructure) {
            throw new UnexpectedTypeException($constraint, ArrayStructure::class);
        }

        foreach ($array as $element) {
            $reqired = null;
            switch ($element['type']) {
                case 'foo':
                    $reqired = "abc";
                case 'bar':
                    $reqired = "xyz";
            }

            if ($reqired) {
                if (array_key_exists($reqired, $element)) {
                    $this->context
                        ->buildViolation($constraint->message)
                        ->addViolation()
                    ;
                }
            }
        }
    }
}

类名称必须必须与Constraint +“ Validator” *

相同

您可以使用创建的自定义验证约束,在所需字段的表单中指定其用途,例如:

// ...
use FooBundle\Validator\Constraints\ArrayStructure;

class FooBarType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add("array", BarType::class, [
                "constraints" => [new ArrayStructure ()]
            ])
        // ...
    }
}

有关完整参考,请参见此link

我希望这会有所帮助。