【问题标题】:Cleanest way to set createdAt timestamp / datetime in object在对象中设置 createdAt 时间戳/日期时间的最简洁方法
【发布时间】: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


【解决方案1】:

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

如果我通过存储库从数据库中获取实体, 构造函数曾经被调用(即 new \DateTime() 被称为 之后直接被数据库值覆盖)?

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

【讨论】:

    猜你喜欢
    • 2017-03-06
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 2011-10-13
    • 2019-01-10
    相关资源
    最近更新 更多