原则:由数据库(即不由PHP)将CURRENT_TIMESTAMP设置为默认值



环顾四周一段时间后,我仍然找不到数据库服务器插入CURRENT_TIMESTAMP的方法(作为INSERT上的默认值(。

问题是:当您将一个对象持久化到数据库中时,缺少的字段会被Doctrine明确设置为NULL。因此,在表定义中设置默认值似乎根本没有任何效果:-(

我不想通过PHP(例如$object->setTimestamp(new DateTime());(设置时间,因为这可能会返回与数据库服务器不同的时间,如下所述:https://stackoverflow.com/a/3705090/1668200

到目前为止我尝试过的:

  • 按字面意思发送NOW(例如$object->setTimestamp('NOW()');(,如下所述:https://stackoverflow.com/a/13850741/1668200
    =>无效:Error: Call to a member function format() on string

  • 在持久化对象之前从对象中删除"timestamp"属性(请参阅https://stackoverflow.com/a/3600758/1668200(也不起作用:无论如何,Doctrine都将该字段设置为NULL。

我发现的任何其他解决方案(包括条令扩展"可时间戳"https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/timestampable.md(使用PHP的时间。

/**
 * @ORMColumn(type="datetime", options={"default": "CURRENT_TIMESTAMP"})
 */
protected $created;     

请记住,如果更新现有表,这将不允许前几行为空。

看看这个:https://stackoverflow.com/a/29384596/3255540它应该解决CCD_ 6的问题并强制SQL CCD_。

UPDATE:这与VasekPurchart\DoctrineDateTimeImmutableTypesBundle不再兼容。而且它不适用于DBAL 2.6条令。看见https://github.com/VasekPurchart/Doctrine-Date-Time-Immutable-Types-Bundle/issues/17


因此,结束这一切,这里有一个循序渐进的说明:

1( 创建一个新类"DateTimeNow";一个好的位置可能是AppBundle/Entity/DateTimeNow.php:

<?php
namespace AppBundleEntity;
class DateTimeNow
{
    public function format() 
    {
        return 'NOW()';
    }
}

2( 在要加时间戳的实体中,添加一个函数,每当保存新实体时(即在每个INSERT上(执行:

public function doPrePersist()
{
    $this->timestamp = new DateTimeNow();
}

3( 将此函数注册为Lifecycle Callback prePersist。有关"注释",请参见http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-预科生。对于YAML:

AppBundleEntityWhatever:
    # ...
    lifecycleCallbacks:
        prePersist: [ doPrePersist ]

就是这样!:-(

现在,当您持久化一个空对象时,这就是结果查询:

INSERT INTO public.whatever(id, text, timestamp) VALUES (?, ?, ?)
Parameters: { 1: null, 2: null, 3: NOW() } 

最新更新