约束不能放在属性或getter上

时间:2016-02-02 21:01:15

标签: php validation constraints symfony

我尝试在symfony 3中创建custom constraint

我有错误

约束App \ Bundle \ MyBundle \ Validator \ Constraints \ Code无法放在属性或getter上

<?php
// vendor/app/mybundle/Validator/Constraints/Code.php

namespace App\Bundle\MyBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;


class Code extends Constraint
{
    public $message = 'Error validate message!!!';
    public function validatedBy()
    {
        return 'alias_name';
    }

    public function getTargets()
    {
      //return self::CLASS_CONSTRAINT; // error "The constraint cannot be put on properties or getters"
      return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT); // working, but $value is a STRING!!!
    }
 }

我的 vendor / app / mybundle / Validator / Constraints / CodeValidator.php

<?php
// vendor/app/mybundle/Validator/Constraints/CodeValidator.php

namespace App\Bundle\MyBundle\Validator\Constraints;

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

class CodeValidator extends ConstraintValidator
{
     public function validate($value, Constraint $constraint)
     {
         $value->getId(); // this code not working, because $value is STRING!!
         $this->context->buildViolation($constraint->message)
             ->atPath('code')
             ->addViolation();
     }

}

我犯了错误?

2 个答案:

答案 0 :(得分:7)

尝试将此添加到您的约束中:

/**
 * @Annotation
 * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
 */

修改

今天早上,我花时间尝试在新的symfony 3安装上实施。

此外,如果您在以下属性中添加@AcmeAssert\Code

use AppBundle\Validator\Constraints as AcmeAssert;

// ...

/**
 * @var string
 * @AcmeAssert\Code
 * @ORM\Column(name="code", type="string")
 */
private $code;

仅验证字段,因此$value表示属性的字段值 例如,如果您在实体的@AcmeAssert\Code媒体资源上分配了$code,那么在提交表单时,您的验证工具的$value将代表您{{1}的字段值} property。。

如果您在实体顶部添加$code,如下所示:

@AcmeAssert\Code

然后,$ value将代表您的完整实体,您可以使用getter进行所需的所有验证。

我已将测试项目添加到存储库中,您可以使用它来查看如何使用这两种方法:sf3-constraint-test

在我的示例中,实体use AppBundle\Validator\Constraints as AcmeAssert; /** * Foo * * @ORM\Table(name="foo") * @AcmeAssert\Code * @ORM\Entity(repositoryClass="AppBundle\Repository\FooRepository") */ class Foo 对属性有约束,AppBundle::Bar对整个实体有约束。

希望它能满足您的需求!

<强> EDIT2

如果您处于yaml映射中,请使用以下内容在整个实体上应用约束,并在约束中通过AppBundle::Foo访问完整对象:

$value

在您的映射之上。

如果您只想在一个属性上应用约束,并使用AppBundle\Entity\AcmeEntity: constraints: - App\Bundle\MyBundle\Validator\Constraints\Code: ~ 访问该字段的值,请保持原样,并在$value上对字符串执行逻辑(值为对应于映射中约束的实体属性的字段),它类似于:

$value

答案 1 :(得分:4)

您创建了一个仅应用于整个实体的约束,例如:

/**
 * @AppAssert\SectionCode
 */
class MyEntity
{
    // ...
}

如果您希望将约束应用于班级成员,请完全删除getTargets()功能。