Symfony 5.3.1中如何为Article模型字段设置默认关联当前登录用户
问题原因
实体类是独立的业务对象,不继承控制器的任何方法,也不直接和请求/安全上下文耦合,所以getUser()方法仅在控制器中可用,不能在实体构造方法中调用,同时实体设计上也不应该和请求上下文强绑定。
适配API Platform的最简解决方案
API Platform 2.6及以上版本自带CurrentUser约束注解,仅需在关联字段上添加该注解即可自动完成用户关联,无需编写额外业务代码:
/* src/Entity/Article.php */ use ApiPlatform\Core\Bridge\Symfony\Validator\Constraint\CurrentUser; use Doctrine\ORM\Mapping as ORM; class Article { // 其余字段省略 /** * @ORM\ManyToOne(targetEntity=User::class) * @ORM\JoinColumn(nullable=false) * @CurrentUser() */ private $submittedBy; // 其余get/set方法省略 }
注解添加后,用户发起POST请求创建Article时,API Platform会自动将当前登录的用户对象赋值给submittedBy字段。
通用解决方案(兼容所有版本)
如果你的API Platform版本低于2.6,或者需要更灵活的自定义逻辑,可以编写事件监听器在实体持久化前完成赋值:
- 新建事件监听器类
/* src/EventListener/ArticleAssociateUserListener.php */ namespace App\EventListener; use ApiPlatform\Core\EventListener\EventPriorities; use App\Entity\Article; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; class ArticleAssociateUserListener implements EventSubscriberInterface { public function __construct(private TokenStorageInterface $tokenStorage) { } public static function getSubscribedEvents() { return [ KernelEvents::VIEW => ['associateUser', EventPriorities::PRE_WRITE], ]; } public function associateUser(ViewEvent $event) { $entity = $event->getControllerResult(); $method = $event->getRequest()->getMethod(); // 仅匹配Article实体的POST创建请求 if (!$entity instanceof Article || Request::METHOD_POST !== $method) { return; } $user = $this->tokenStorage->getToken()?->getUser(); if ($user instanceof \App\Entity\User) { $entity->setSubmittedBy($user); } } }
- 该类会被Symfony自动装配注册,无需额外配置即可生效。
内容的提问来源于stack exchange,提问作者NoChecksum
相关产品推荐
相关产品推荐

