Doctrine - Add default time stamp to entity like N

2020-02-09 08:07发布

问题:

Following the Doctrine guidelines I understand how to set a default value for an Entity, but what if I wanted a date/time stamp?

  • http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/faq.html

My problem is my database has a default of NOW() on a field but when I use Doctrine to insert a record the values are null or blank but the rest of the insert happened.

Also since Doctrine says to declare the default as a const, this also creates a problem.

Suggestions?

回答1:

Ok I found the solution:

  • https://doctrine-orm.readthedocs.org/en/latest/reference/php-mapping.html?highlight=callback
  • http://doctrine-orm.readthedocs.org/en/latest/reference/events.html#lifecycle-events

The prePersist option is what I'm doing.

Make sure you define in the annotations

<?php

/** @Entity 
 *  @HasLifecycleCallbacks 
 */
class User

and here is the function example they offer

/** 
 *  @PrePersist 
 */
public function doStuffOnPrePersist()
{
    $this->createdAt = date('Y-m-d H:i:s');
}

And if you're using ORM like I am

<?php

/** @ORM\Entity 
 *  @ORM\HasLifecycleCallbacks 
 */
class User

and here is the function example they offer

/** 
 *  @ORM\PrePersist 
 */
public function doStuffOnPrePersist()
{
    $this->createdAt = date('Y-m-d H:i:s');
}


回答2:

In my experience it is best to put everything in your Entities and not try to force your database to bypass the ORM.

<?php
namespace Phill\PaffordBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * Stack
 * @ORM\Table()
 */
class Stack
{
  /**
   * @var integer
   * @ORM\Column(type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

  /**
   * @var \DateTime
   * @ORM\Column(type="datetime")
   */
  private $startDate;

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

}


回答3:

In order to have exactly NOW() you could extend Doctrine\DBAL\Types\DateTimeType.

Other method:

class DateTimeNow
{
    public function format() 
    {
        return 'NOW()';
    }
}

Then you can use $entity->setFieldDatetime(DateTimeNow()) instead of $entity->setFieldDatetime(new Datetime()).
Note: The method format() is automatically called by Doctrine.



回答4:

Try this:

/**
 * @var \DateTime
 *
 * @Column(name="created", type="datetime", nullable=false)
 */
private $created;

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

The whatever $value you assign to created field, has to be able to handle this call:

$value->format('Y-m-d H:i:s');

See relevant Doctrine code line

Tested to work with Doctrine 2.5.4

Note: above works at creation time but not on update by default -- you have to manually set created property to new \DateTime()when you do an update or look into doStuffOnPrePersist

/** @PrePersist */
public function doStuffOnPrePersist()
{
    $this->created = date('Y-m-d H:i:s');
}


回答5:

For PostgreSQL, you should just be able to pass string value of now for the field to get the timestamp to function.



回答6:

You can use TimestampableEntity Trait for automatically create created_at and updated_at fields in you Entity;

First install doctrine-extensions;

composer require gedmo/doctrine-extensions

Secondly add trait into your Entity Class;

use Gedmo\Timestampable\Traits\TimestampableEntity;

    /**
     * @ORM\Entity(repositoryClass="App\Repository\ProjectRepository")
     */
    class Project
    {
        use TimestampableEntity;