如果Symfony Form中的某些字段为空,则一个字段不应为空

时间:2014-02-19 08:06:03

标签: php symfony

在我的Symfony 2(2.4.2)应用程序中,有一个由3个字段组成的表单类型。

我希望验证如下:如果field Afield B为空,field C不应为空。这意味着至少有一个字段应该接收一些数据。

目前,我检查控制器中收到的数据。有更推荐的方法吗?

3 个答案:

答案 0 :(得分:13)

除了编写自定义验证器之外,还有更简单的解决方案。最简单的可能是表达式约束:

class MyEntity
{
    private $fieldA;

    private $fieldB;

    /**
     * @Assert\Expression(
     *     expression="this.fieldA != '' || this.fieldB != '' || value != ''",
     *     message="Either field A or field B or field C must be set"
     * )
     */
    private $fieldC;
}

您还可以向类中添加验证方法,并使用Callback约束对其进行注释:

/**
 * @Assert\Callback
 */
public function validateFields(ExecutionContextInterface $context)
{
    if ('' === $this->fieldA && '' === $this->fieldB && '' === $this->fieldC) {
        $context->addViolation('At least one of the fields must be filled');
    }
}

该方法将在课程验证期间执行。

答案 1 :(得分:3)

这可能是Custom Validation Constraint的用例。我自己没有使用它,但基本上你创建了一个Constraint和一个Validator。然后,在Constraint

中指定config/validation.yml
Your\Bundle\Entity\YourEntity:
    constraints:
        - Your\BundleValidator\Constraints\YourConstraint: ~

实际验证由您的Validator完成。您可以告诉Symfony将整个实体传递给您的validate方法以访问多个字段:

public function getTargets()
{
    return self::CLASS_CONSTRAINT;
}

您的validate

public function validate($entity, Constraint $constraint)
{
    // Do whatever validation you need
    // You can specify an error message inside your Constraint
    if (/* $entity->getFieldA(), ->getFieldB(), ->getFieldC() ... */) {
        $this->context->addViolationAt(
            'foo',
            $constraint->message,
            array(),
            null
        );
    }
}

答案 2 :(得分:0)

您可以使用Group Sequence Providers执行此操作,例如:

use Symfony\Component\Validator\GroupSequenceProviderInterface;

/**
 * @Assert\GroupSequenceProvider
 */
class MyObject implements GroupSequenceProviderInterface
{
    /**
     * @Assert\NotBlank(groups={"OptionA"})
     */
    private $fieldA;

    /**
     * @Assert\NotBlank(groups={"OptionA"})
     */
    private $fieldB;

    /**
     * @Assert\NotBlank(groups={"OptionB"})
     */
    private $fieldC;

    public function getGroupSequence()
    {
        $groups = array('MyObject');

        if ($this->fieldA == null && $this->fieldB == null) {
            $groups[] = 'OptionB';
        } else {
            $groups[] = 'OptionA';
        }

        return $groups;
    }
}

没有测试过,但我认为它会起作用