如何创建返回ID数组的方法?解决Doctrine序列化相关报错
问题根因
两次报错以及第一版代码的隐性问题核心有三点:
- 第一版代码存在递归死循环:
getEvent()方法内部调用$this->getEvent(),会无限递归直到触发内存上限。 @ORM\OneToMany标注的$event属性是集合类型:构造函数里初始化为ArrayCollection,Doctrine懒加载时会替换为PersistentCollection,本质是多个Event实体的集合,不是单个Event对象,直接序列化整个集合会输出完整的Event对象数组,不符合接口需要返回ID数组的要求,触发第一次报错。- 第二版代码没有处理集合类型:直接对返回的集合对象调用
getId()方法,但集合本身是对象容器,没有getId()方法,只有集合内的单个Event实体才有ID属性,因此触发未定义方法的报错。
修复方案
首先去掉$event属性上的@Serializer\Expose()注解,避免直接序列化整个关联集合,保留Doctrine关联需要的默认集合返回方法,新增虚拟属性遍历集合提取需要的ID字段即可:
/** * @ORM\OneToMany(targetEntity="App\Entity\Event", mappedBy="project") */ private $event; public function __construct() { $this->enabled = false; $this->event = new ArrayCollection(); } /** * 供Doctrine内部调用的关联getter,直接返回集合对象 */ public function getEvent() { return $this->event; } /** * @return array 返回Event ID数组 * * @Serializer\VirtualProperty() * @Serializer\SerializedName("event") */ public function getEventData(): array { return $this->getEvent()->map(function($event) { return $event->getId(); })->toArray(); }
注意事项
- 如果接口要求返回结构为
[{id: 1}, {id: 2}]的对象数组,把map回调里的返回值改为['id' => $event->getId()]即可。 - 不要在
OneToMany、ManyToMany类型的关联属性上直接加@Serializer\Expose注解,除非明确需要序列化关联实体的全量字段,否则极易出现输出结构不符合预期、循环引用序列化报错的问题。 - Doctrine的
PersistentCollection和ArrayCollection都内置了map、filter、toArray等遍历处理方法,不需要手动写foreach循环处理集合内容。
内容的提问来源于stack exchange,提问作者peace_love
相关产品推荐
相关产品推荐

