如何在Symfony2中实现动态(即未缓存)原则声明?

如何在Symfony2中实现动态(即未缓存)原则声明?,symfony,caching,doctrine-orm,Symfony,Caching,Doctrine Orm,我的Symfony2项目中有一个条令实体,它使用自定义断言/约束来检查给定日期值是否在给定日期之前和/或之后。这类似于以下简化代码: 在我的实体类中: /** *@var\DateTime * *@ORM\Column(name=“entry\u entered\u at”,type=“date”,nullable=true) *@appbundleasert\DateRangeConstraint(max=“今天”) */ 私人$entryEnteredAt; 相应DateRangeCons

我的Symfony2项目中有一个条令实体,它使用自定义断言/约束来检查给定日期值是否在给定日期之前和/或之后。这类似于以下简化代码:

在我的实体类中:

/**
*@var\DateTime
*
*@ORM\Column(name=“entry\u entered\u at”,type=“date”,nullable=true)
*@appbundleasert\DateRangeConstraint(max=“今天”)
*/
私人$entryEnteredAt;
相应DateRangeConstraint类的相关代码段:

new\DateTime($this->max)
如你所见,我想检查一下,日期是否在今天之前。\DateTime构造函数能够将其解析为当前的DateTime对象。好东西,很好用

问题 但事实证明,Symfony2缓存了所有这些条令注释,所以今天总是解决到今天,缓存最后被清除,我的约束产生了很好的表单错误

作为目前的解决办法,我每天都会清除缓存,但我需要一个更好的解决方案

问题 所以问题是,您有什么建议,如何在Symfony2中实现这样一个动态断言/约束

我可以在表单中实现约束,但它应该在实体的域中

编辑: 我将其作为答案发布,并将其标记为解决方案

public function __construct()
{
    $this->entryEnteredAt = new \DateTime();
}
对于您的用例来说,这是一个解决方案吗?(在new YourEntity()上,您将为entryEnteredAt属性设置一个今天日期)

您还可以使用LifecycleCallbacks,下面是一个preUpdate示例(还有一些,如PrePersist):

在类实体的顶部:

 * @ORM\HasLifecycleCallbacks()

我特别建议你看看

我不会复制粘贴整个代码,只是你必须更改的部分


扩展
约束

src/Acme/DemoBundle/Validator/Constraints/CheckEntryEnteredAt.php

解决方案和一些答案
事实证明,内置的范围验证器也能够验证日期范围。所以我根本不需要我的自定义验证器

深入研究内置范围约束和基本约束类给出了原因,为什么内置验证器可以使用动态参数,比如今天的
,而不是我不正确实现的自定义验证器。约束基类有一个_sleep()方法,该方法仅在序列化时存储对象变量及其当前值。因此,当我们不使用自定义的_wakeup()方法重新初始化对象时(这是一种错误的解决方法),我们只获取缓存的参数

因此,除了内置范围约束已经解决了我的问题之外,我还应该在自定义DateRangeConstraintValidator而不是缓存的自定义DateRangeConstraint中完成动态
new\DateTime($constraint->max)
工作。只需查看Symfony\Component\Validator\Constraints\Range和Symfony\Component\Validator\Constraints\RangeValidator就可以看到这一点

经验教训
自定义约束类将被序列化和缓存,因此不应执行任何动态操作。只需验证选项并定义消息和内容。动态验证操作(尤其是动态参数的初始化)必须在自定义ConstraintValidator类中完成。

我不想将日期设置为今天,但希望确保给定日期在今天之前(或之后)。但我会看看生命周期回调,也许我可以在那里实现检查。您的@AppBundleAsert\DateRange约束来自哪里?这不是已经是一个自定义约束了吗?那么为什么不检查约束内的条件呢?@LBA是的,这是一个自定义约束。我的意图是,这个约束可以获得一个有效的DateTime构造函数字符串作为参数,因此可以重用它。实际上,Symfony序列化DateRangeConstraint对象并缓存它。因此,它不会在每次调用时被初始化,而是在缓存时以初始化状态执行。我建议您发布解决方案,您将能够接受您的答案,这将结束问题。@A.L您是对的,我提取了我的解决方案。:)这可能是一个解决方案,但我想编写一个通用的DateRangeConstraint,而不是为我使用的每个字段编写一个特定的验证器。就像其他验证器一样。事实证明,该范围还可以处理日期,所以我根本不需要vustom验证器。无论如何,谢谢你。:)@spackmat:请随意在您的解决方案中添加答案,它可能会帮助其他用户解决相同的问题。
/** 
* Set updatedAt 
* 
* @ORM\PreUpdate 
*/  
public function setUpdatedAt()  
{  
    $this->updatedAt = new \DateTime();  
}