【问题标题】:Automatic values for updated_at, created_at in Doctrine在 Doctrine 中为 updated_at、created_at 自动取值
【发布时间】:2013-06-23 16:47:42
【问题描述】:

我想让我的Doctrine 实体中的字段updated_atcreated_at 自动更新。

在 Ruby on Rails 模型中有 2 个字段:updated_atcreated_at

描述可以在这里找到:http://guides.rubyonrails.org/migrations.html#migration-overview:

timestamps 宏添加了两列,created_at 和 updated_at。如果存在这些特殊列,则它们会由 Active Record 自动管理。

我可以在 Doctrine 2 中启用类似的功能吗?

【问题讨论】:

    标签: php doctrine-orm


    【解决方案1】:
    1. 您可以在__construct方法中调用$this->setCreatedAt(new \DateTime())
    2. 您可以使用Life Cycle Callbacks
    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
    */
    public function updatedTimestamps(): void
    {
        $this->setUpdatedAt(new \DateTime('now'));    
        if ($this->getCreatedAt() === null) {
            $this->setCreatedAt(new \DateTime('now'));
        }
    }
    

    并且不要忘记添加到实体类符号中: @ORM\HasLifecycleCallbacks

    【讨论】:

    • 3.在构造函数中使用:$this->publishedAt = new \DateTime();$this->updatedAt = new \DateTime();
    • @VladimirCh 即使实体中没有任何其他内容被更新,也会设置 updatedAt。
    • @marcguyer 不正确,因为构造函数只会在第一次创建时被教义调用。
    • 'now' 不需要 new \DateTime('now'),因为它是默认值
    【解决方案2】:

    如果您想单独处理它们,这是另一种选择。

    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     * @ORM\Table(name="person")
     * @ORM\HasLifecycleCallbacks
     */
    class Person
    {
        ..........
    
        /**
         * @var datetime $created
         *
         * @ORM\Column(type="datetime")
         */
        protected $created;
    
        /**
         * @var datetime $updated
         * 
         * @ORM\Column(type="datetime", nullable = true)
         */
        protected $updated;
    
    
        /**
         * Gets triggered only on insert
    
         * @ORM\PrePersist
         */
        public function onPrePersist()
        {
            $this->created = new \DateTime("now");
        }
    
        /**
         * Gets triggered every time on update
    
         * @ORM\PreUpdate
         */
        public function onPreUpdate()
        {
            $this->updated = new \DateTime("now");
        }
    
        ..........
    }
    

    【讨论】:

    • 很好的答案,但如果您想按此字段排序,updated_at 在第一次更新之前获得空值这一事实可能会很痛苦。
    • @El_Matella 您只需更改onPrePersist() 函数,使其同时设置createdupdated。如果您之前在生产环境中没有这样做,也可以轻松地在数据库中修复。
    • 是的,我就是这么做的 :)
    • 如何使用 Yml 文件在 createdAt 字段中插入当前日期时间?
    • 非常好。对于未来的用户,不要忘记在类注释中添加@ORM\HasLifecyleCallbacks(这会节省我一些时间)。
    【解决方案3】:

    对我来说最方便的解决方案是StofDoctrineExtensionsBundleTimestampable 功能。

    简单的配置,之后您可以通过添加两个简单的annotations 来自动填写EntitycreatedAtupdatedAt 字段,例如:

    @Gedmo\Mapping\Annotation\Timestampable(on="create")

    和/或

    @Gedmo\Mapping\Annotation\Timestampable(on="update")

    例如

    /**
     * @var \DateTime
     * @Gedmo\Mapping\Annotation\Timestampable(on="create")
     * @Doctrine\ORM\Mapping\Column(type="datetime")
     */
    protected $createdAt;
    
    /**
     * @var \DateTime
     * @Gedmo\Mapping\Annotation\Timestampable(on="update")
     * @Doctrine\ORM\Mapping\Column(type="datetime")
     */
    protected $updatedAt;
    

    PHP 中没有任何冗余代码。

    【讨论】:

    • 如果您已经使用 StofDoctrineExtensions(可能是我们大多数人),这是最好的解决方案。应该注意的是,您需要启用时间戳:symfony.com/doc/master/bundles/StofDoctrineExtensionsBundle/…
    • 使用 Symfony 4.0+ composer require stof/doctrine-extensions-bundle 安装(使用 Flex)
    • 我在 symfony Flex 中使用这种方法,对我来说唯一缺少的部分是我必须更新 ./config/bundles.php 以包含 Stof 包:Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
    【解决方案4】:

    您也可以将其实现为 trait - 像这样:

    <?php
    
    namespace App\Entity\Traits;
    
    use DateTime;
    use DateTimeInterface;
    use Exception;
    
    /**
     * Trait TimeStampableTrait
     * @package App\Entity\Trait
     */
    trait TimeStampableTrait
    {
        /**
         * @ORM\Column(type="datetime")
         */
        private $createdAt;
    
        /**
         * @ORM\Column(type="datetime")
         */
        private $updatedAt;
    
        /**
         * @return DateTimeInterface|null
         * @throws Exception
         */
        public function getCreatedAt(): ?DateTimeInterface
        {
            return $this->createdAt ?? new DateTime();
        }
    
        /**
         * @param DateTimeInterface $createdAt
         * @return $this
         */
        public function setCreatedAt(DateTimeInterface $createdAt): self
        {
            $this->createdAt = $createdAt;
    
            return $this;
        }
    
        /**
         * @return DateTimeInterface|null
         */
        public function getUpdatedAt(): ?DateTimeInterface
        {
            return $this->updatedAt ?? new DateTime();
        }
    
        /**
         * @param DateTimeInterface $updatedAt
         * @return $this
         */
        public function setUpdatedAt(DateTimeInterface $updatedAt): self
        {
            $this->updatedAt = $updatedAt;
    
            return $this;
        }
    
        /**
         * @ORM\PrePersist()
         * @ORM\PreUpdate()
         */
        public function updateTimestamps(): void
        {
            $now = new DateTime();
            $this->setUpdatedAt($now);
            if ($this->getId() === null) {
                $this->setCreatedAt($now);
            }
        }
    }
    

    将此特征添加到您的实体(不要忘记@ORM\HasLifecycleCallbacks() 符号):

    <?php
    
    namespace App\Entity;
    
    use App\Entity\Traits\TimeStampableTrait;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity(repositoryClass="App\Repository\MyEntityRepository")
     * @ORM\HasLifecycleCallbacks()
     */
    class MyEntity
    {
        use TimeStampableTrait;
    }
    

    【讨论】:

      【解决方案5】:

      我建议使用可时间戳特征

      https://symfonycasts.com/screencast/symfony4-doctrine/timestampable

      use Gedmo\Timestampable\Traits\TimestampableEntity;
      
      class Article
      {
          use TimestampableEntity;
      }
      

      将自动添加所有适当的功能

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-16
        • 2016-08-22
        • 1970-01-01
        • 1970-01-01
        • 2015-07-05
        • 1970-01-01
        • 2017-05-26
        • 1970-01-01
        相关资源
        最近更新 更多