web-dev-qa-db-fra.com

Doctrine - Ajouter un horodatage par défaut à une entité comme NOW ()

En suivant les directives de la doctrine, je comprends comment définir une valeur par défaut pour une entité, mais que se passe-t-il si je voulais un horodatage?

Mon problème est que ma base de données a la valeur par défaut NOW () sur un champ, mais lorsque j'utilise Doctrine pour insérer un enregistrement, les valeurs sont nulles ou vides, mais le reste de l'insertion s'est produit.

De plus, puisque Doctrine dit de déclarer la valeur par défaut en tant que const, cela crée également un problème.

Suggestions?

13
Phill Pafford

Ok j'ai trouvé la solution:

L'option prePersist est ce que je fais.

Assurez-vous de définir dans les annotations 

<?php

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

et voici l'exemple de fonction qu'ils offrent

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

Et si vous utilisez ORM comme moi

<?php

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

et voici l'exemple de fonction qu'ils offrent

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

D'après mon expérience, il est préférable de tout mettre dans vos entités et de ne pas essayer de forcer votre base de données à contourner l'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();
  }

}
8
David Baucum

Pour avoir exactement NOW() vous pouvez étendre Doctrine\DBAL\Types\DateTimeType.

Autre méthode:

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

Ensuite, vous pouvez utiliser $entity->setFieldDatetime(DateTimeNow()) au lieu de $entity->setFieldDatetime(new Datetime()).
Remarque: La méthode format() est automatiquement appelée par Doctrine.

4
Alexandre

Essaye ça:

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

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

Quel que soit le $value que vous affectez au champ created, il doit être capable de gérer cet appel:

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

Voir Ligne de code de la doctrine pertinente

Testé pour fonctionner avec Doctrine 2.5.4

Remarque: ci-dessus fonctionne au moment de la création, mais pas lors de la mise à jour par défaut. Vous devez définir manuellement la propriété created sur new \DateTime()lorsque vous effectuez une mise à jour ou que vous regardez dans doStuffOnPrePersist.

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

Pour PostgreSQL, vous devriez juste pouvoir passer la valeur de chaîne now pour que le champ obtienne l’horodatage à fonctionner.

0
Mike Brant