【问题标题】:The constraint cannot be put on properties or getters约束不能放在属性或吸气剂上
【发布时间】:2016-05-11 20:43:00
【问题描述】:

我尝试在 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!!!
    }
 }

我的供应商/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();
     }

}

我在哪里做错了?

【问题讨论】:

    标签: php validation constraints symfony


    【解决方案1】:

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

    /**
     * @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 表示属性的字段值。
    例如,如果您在实体中的$code 属性上分配@AcmeAssert\Code,则在提交表单时,您的验证器的$value 将代表您的$code 属性的字段值。

    如果您在实体顶部添加@AcmeAssert\Code,如下所示:

    use AppBundle\Validator\Constraints as AcmeAssert;
    
    /**
     * Foo
     *
     * @ORM\Table(name="foo")
     * @AcmeAssert\Code
     * @ORM\Entity(repositoryClass="AppBundle\Repository\FooRepository")
     */
    class Foo
    

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

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

    在我的示例中,实体AppBundle::Bar 具有属性约束,AppBundle::Foo 具有整个实体的约束。

    希望这是你需要的!

    EDIT2

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

    AppBundle\Entity\AcmeEntity:
        constraints:
            - App\Bundle\MyBundle\Validator\Constraints\Code: ~
    

    在您的映射之上。

    如果您只想对一个属性应用约束,并使用 $value 访问字段的值,请保持原样并在 $value 上执行逻辑,这是一个字符串(字段的值对应于实体属性在映射中受限),类似于:

    AppBundle\Entity\AcmeEntity:
        properties:
                # ...
                code:
                    - App\Bundle\MyBundle\Validator\Constraints\Code: ~
    

    【讨论】:

    • 我再次改变我的@chalasr 外观。请
    • 我已根据您的需要进行了更改。
    • 非常感谢,这对我有帮助。我使用 yml 文件进行映射和验证。也许这就是问题所在?你认为这重要吗?确定只使用注解吗?
    • 我认为这不会导致问题,请尝试检查我的代码和您的代码以找出问题所在。我没有足够的代码来定位代码中的错误。但是约束之上的@Annotation 是强制性的。而且映射格式非常个人化,我只对实体使用注解,现在我在控制器中使用它,因为 FOSRestBundle,它是 Symfony 的最佳实践。
    【解决方案2】:

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

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

    如果您希望将约束应用于类成员,请完全删除您的 getTargets() 函数。

    【讨论】:

    • @AppAssert\SectionCode("propertyName") 怎么样?
    • @jason-roman 我更改 getTargets public function getTargets() { return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);但在 validate() 方法中 $value 变量不是我的实体的对象,是字符串
    • 您是在验证整个实体,还是仅验证实体的一个属性?如果是实体,则将其保留为self::CLASS_CONSTRAINT,但请在您尝试应用约束的位置发布代码,而不仅仅是约束和验证器。
    • 这个问题应该被关闭,因为这个答案解决了你的主要问题(问题是关于)
    • 在 Symfony 的 3.4 版本中(还没有检查 4),实际上你需要重写 getTargets() 方法。如果你查看 Constraint::getTargets() 你会看到它默认返回self::PROPERTY_CONSTRAINT;。覆盖 getTargets() 方法并从中返回 return parent::CLASS_CONSTRAINT; 是我解决此问题的方法。
    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多