You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在EasyAdmin中实现记录创建与更新时自动填充date_create和date_update字段的方法

在EasyAdmin中实现记录创建与更新时自动填充date_create和date_update字段的方法

嘿,我来帮你搞定这个自动填充时间字段的需求!其实有两种靠谱的方式可以实现,我都给你详细说说,你可以根据自己的情况选:

方式一:用Doctrine生命周期回调(推荐,全局生效)

这种方式最稳妥,不管你是通过EasyAdmin后台操作,还是用命令行、API修改实体,时间字段都会自动填充,不会有遗漏。

第一步:在实体类里添加字段

先在你的实体类(比如YourEntity.php)里定义这两个时间字段,记得加上Doctrine的注解:

use Doctrine\ORM\Mapping as ORM;

// ... 其他use语句

class YourEntity
{
    // ... 你的其他字段

    /**
     * @ORM\Column(type="datetime_immutable")
     */
    private $dateCreate;

    /**
     * @ORM\Column(type="datetime_immutable")
     */
    private $dateUpdate;

    // 别忘了生成对应的getter和setter方法哦!
    public function getDateCreate(): ?\DateTimeImmutable
    {
        return $this->dateCreate;
    }

    public function setDateCreate(\DateTimeImmutable $dateCreate): self
    {
        $this->dateCreate = $dateCreate;
        return $this;
    }

    public function getDateUpdate(): ?\DateTimeImmutable
    {
        return $this->dateUpdate;
    }

    public function setDateUpdate(\DateTimeImmutable $dateUpdate): self
    {
        $this->dateUpdate = $dateUpdate;
        return $this;
    }
}

第二步:创建实体监听器类

新建一个监听器文件src/EventListener/EntityTimestampListener.php,用来处理创建和更新时的时间填充:

namespace App\EventListener;

use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\ORM\Events;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use App\Entity\YourEntity;

#[AsEntityListener(event: Events::prePersist, method: 'prePersist', entity: YourEntity::class)]
#[AsEntityListener(event: Events::preUpdate, method: 'preUpdate', entity: YourEntity::class)]
class EntityTimestampListener
{
    // 当实体第一次保存(INSERT)时触发
    public function prePersist(YourEntity $entity, LifecycleEventArgs $event): void
    {
        $now = new \DateTimeImmutable();
        $entity->setDateCreate($now);
        $entity->setDateUpdate($now);
    }

    // 当实体更新(UPDATE)时触发
    public function preUpdate(YourEntity $entity, LifecycleEventArgs $event): void
    {
        $entity->setDateUpdate(new \DateTimeImmutable());
        
        // 这里要注意:Doctrine默认不会自动检测datetime字段的变化,所以需要手动触发更新
        $entityManager = $event->getObjectManager();
        $metadata = $entityManager->getClassMetadata(get_class($entity));
        $entityManager->getUnitOfWork()->recomputeSingleEntityChangeSet($metadata, $entity);
    }
}

第三步:关联监听器和实体

在你的实体类顶部添加注解,告诉Doctrine这个实体要使用刚才的监听器:

/**
 * @ORM\EntityListeners({"App\EventListener\EntityTimestampListener"})
 */
class YourEntity
{
    // ... 实体内容
}

方式二:用EasyAdmin内置事件(仅后台操作生效)

如果你只需要在EasyAdmin后台操作时自动填充时间,也可以直接在CrudController里处理:

打开你的YourEntityCrudController.php,修改成这样:

use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityPersistedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use App\Entity\YourEntity;

class YourEntityCrudController extends AbstractCrudController implements EventSubscriberInterface
{
    public static function getEntityFqcn(): string
    {
        return YourEntity::class;
    }

    // 声明要监听的事件
    public static function getSubscribedEvents(): array
    {
        return [
            BeforeEntityPersistedEvent::class => 'setCreateAndUpdateDate',
            BeforeEntityUpdatedEvent::class => 'setUpdateDate',
        ];
    }

    // 创建记录时填充两个时间字段
    public function setCreateAndUpdateDate(BeforeEntityPersistedEvent $event): void
    {
        $entity = $event->getEntity();
        if (!$entity instanceof YourEntity) {
            return;
        }

        $now = new \DateTimeImmutable();
        $entity->setDateCreate($now);
        $entity->setDateUpdate($now);
    }

    // 更新记录时只更新date_update字段
    public function setUpdateDate(BeforeEntityUpdatedEvent $event): void
    {
        $entity = $event->getEntity();
        if (!$entity instanceof YourEntity) {
            return;
        }

        $entity->setDateUpdate(new \DateTimeImmutable());
    }
}

最后提醒一下:两种方式都需要确保你的实体类里有对应的setter方法,不然没法给字段赋值哦!

备注:内容来源于stack exchange,提问作者Necro The Human

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:03:09