在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
相关产品推荐
相关产品推荐

