2012-12-12 30 views
13

這樣的實體添加默認時間戳根據Doctrine指導原則,我瞭解如何爲實體設置默認值,但如果我想要日期/時間戳,該怎麼辦?學說 - 爲NOW()

我的問題是我的數據庫有一個默認的NOW()上的一個字段,但是當我使用Doctrine插入一條記錄的值是零或空白,但刀片的其餘部分發生。

此外,由於Doctrine說要將默認值聲明爲const,這也會產生問題。

對此提出建議?

回答

21

好,我找到了解決辦法:

prePersist選擇是我在做什麼。

確保您在註釋

<?php 

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

這裏定義的功能例如像我

<?php 

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

,它們的價格

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

如果你正在使用ORM這裏是他們提供的功能示例

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

*'Y-m-d H:i:s'是適當的日期格式字符串 – redolent

+0

謝謝@redolent,修正了 –

+0

有沒有一種方法可以實現這一點,而不使用PHP註釋的憎惡? – Sejanus

0

對於PostgreSQL,您應該只能傳遞字段值now來獲取時間戳的功能。

+0

謝謝,使用PostgreSQL 9.x和改變從現在的默認值時, ()到CURRENT_TIMESTAMP,但它恢復到now()。還創建了一個測試表並將datetime列設置爲CURRENT_TIMESTAMP,但也恢復爲now()。任何其他想法? –

+0

對不起,沒有意識到它是Postgres。我正在給PHP用戶更常見的MySQL提供評論。爲PostgreSQL添加了標籤。我也更新了我的答案。 –

+0

對不起,沒有工作,DateTime問題時傳遞字符串NOW –

7

根據我的經驗,最好是將所有內容放入實體中,而不是強制數據庫繞過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(); 
    } 

} 
+1

我不同意,這是爲什麼:ORM可以改變,如果我做原始SQL,還有其他的原因,但是這至少應該在數據庫端處理以保證數據的完整性 –

+0

然後它只取決於你的需求。通常在使用Doctrine時,開發人員打算編程到ORM並將DB用作後端。 如果情況並非如此,那麼就像你所暗示的那樣,這些東西需要用到數據庫。 我認爲對於那些只希望與ORM接口的人來說,這是更好的解決方案。 –

+0

我認爲值得注意的是,這個解決方案和@ PhillPafford的上述都是很好的解決方案。這項工作有一個重要的區別。在我的解決方案中,時間戳是在實體首次實例化時創建的。在這個解決方案中,時間戳在它被保存到數據庫時被設置。 –

4

爲了恰好有NOW()可以擴展Doctrine\DBAL\Types\DateTimeType

其他方法:

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

然後你可以使用$entity->setFieldDatetime(DateTimeNow())而不是$entity->setFieldDatetime(new Datetime())
注意:方法format()被Doctrine自動調用。

+0

哪裏(即在哪個文件中)放置此代碼(在Symfony中)?謝謝! –

+0

@ThomasLandauer我做了durty,並直接在需要使用它的文件中...但是最好在供應商文件夾中創建一個包或者類似的東西。 – Alexandre

+0

這個答案是目前使用數據庫服務器的時間(而不是PHP的時間)的唯一解決方案。這是爲什麼這是一件好事:http://stackoverflow.com/a/3705090/1668200 –

1

試試這個:

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

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

的分配給created場無論$value,必須能夠處理這種呼叫:

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

relevant Doctrine code line

測試與學說工作2.5.4

注意:上述工作在創建時間而不是由默認的更新 - 你必須手動設置created屬性new \DateTime()當你做一個更新或可考慮doStuffOnPrePersist

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

這是如何工作的您?我得到錯誤:錯誤:調用一個成員函數的格式()的字符串,它是有道理的,因爲「CURRENT_TIMESTAMP」是字符串:/ –

+0

哈,我得到了同樣的錯誤! (我一直在使用這種讀取數據只) – Dennis

+0

@Darius,現在就來試試(見更新答案) – Dennis