【发布时间】:2017-05-05 11:27:03
【问题描述】:
我已经遇到过这个问题好几次了,我永远不确定处理它的最佳/最干净的方法。我想在 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();
}
我觉得它有点不雅,因为它有点副作用,但也许还可以。另一个缺点是我必须等待它被持久化到数据库中才能获得createdAt。
类似的方法是使用 DoctrineExtensions' Timestampable。
选项 4:数据库中的默认值
在 Symfony 类 Doctrine 注释中,您可以为 $createdAt 设置默认值,但我觉得这有点不稳定。类似的东西
/**
* @var \DateTime
* @ORM\Column(name="created_at", type="datetime", options={"default" : "CURRENT_TIMESTAMP"})
*/
(没有测试代码,可能需要"NOW()"?)但这更依赖于数据库。
所以我的问题是,哪种方法最干净还是取决于具体情况?
【问题讨论】:
-
您可以丢弃选项 2。表达式不允许作为属性默认值。属性初始化,必须是一个常量值——也就是说,它必须能够在编译时被评估,并且不能依赖运行时信息才能被评估。
-
这个问题不适合 StackOverflow,也许更适合 CodeReview?即便如此,也没有正确的答案,只有意见。正如“干净”是一种观点一样。我会在事件监听器(而不是实体)中选择选项 3,因为我觉得它可以更好地分离关注点
标签: php symfony class doctrine