2017-05-05 64 views
1

我已经有过这个问题几次,我不知道最好/最干净的方式来处理它。我想在Symfony类/对象中创建一个createdAt(时间戳/日期时间)字段。我知道有几种方法可以处理这个问题,但我想问问,是否有一种“最干净”的方式来实现它。最干净的方法来设置对象的时间戳/日期时间

选项1:创建构造(目前最喜欢的)

public function __construct() 
{ 
    $this->createdAt = new \DateTime(); 
} 

我喜欢这个最大,因为它是明确的,它是“建设”过程中设置。

一个连接的问题是,如果我通过一个存储库从数据库中获取一个实体,那么这个构造函数是否会被调用(即调用new \DateTime()后直接被数据库值覆盖)?

选项2:类

class MyClass { 

    protected $createdAt = new \DateTime(); 

    /** ... */ 
} 

这是好的默认值,我想?

方案3:生命周期回调

/** 
* @PrePersist 
*/ 
public function onPrePersistCreated() 
{ 
    $this->createdAt = new \DateTime(); 
} 

我觉得有点unelegant,因为它有点的副作用,但也许是好的。另一个缺点是,我不得不等待它坚持到我的数据库获得createdAt

类似的将使用DoctrineExtensions'Timestampable

方案4:在数据库

在Symfony的类学说注释您可以$createdAt设置默认值默认值,但我觉得这有点不稳定。像

/** 
* @var \DateTime 
* @ORM\Column(name="created_at", type="datetime", options={"default" : "CURRENT_TIMESTAMP"}) 
*/ 

东西(没有测试代码,也许"NOW()"需要?)但是,这是连上数据库更加依赖。

所以我的问题是,这是最干净的方式还是取决于案件?

+0

您可以丢弃选项2.不允许将表达式作为属性的默认值。属性初始化必须是一个常量值 - 也就是说,它必须能够在编译时进行评估,并且不能依赖运行时信息进行评估。 – arbogastes

+4

这个问题不适合StackOverflow,也许更适合[CodeReview](https://codereview.stackexchange.com/)?即使那样,也没有适当的答案,只有意见。正如“干净”是一个意见。我会选择eventlistener(而不是实体)中的选项3,因为我觉得它更好地分离了关注点 – kero

回答

0

选项1和3是有效的,2是不可能的,4是难以实现的。

如果我通过一个存储库中获得实体从数据库中,将 构造曾经被称为(即新\日期时间()被称为是 覆盖与数据库值后直接)?

当从数据库中提取实体时,不会调用构造函数,使用代理对象时,构造函数会在实体加载时覆盖您的构造函数。然后,构造函数只在第一次创建实体时调用一次。