Symfony 3(Doctrine)中findAll返回超大响应的问题排查
为什么Doctrine的findAll()返回庞大响应,而QueryBuilder+HYDRATE_ARRAY正常?
这事儿我太熟了!核心原因其实是Doctrine的findAll()默认返回的是实体对象实例,而非纯数组,这些对象里藏了很多ORM内部的“额外信息”,才导致var_dump出来的内容无比臃肿。
具体拆解一下:
findAll()的默认行为:findAll()默认使用HYDRATE_OBJECThydration模式,返回的是Article实体的对象集合。每个实体对象不仅包含你定义的业务字段(比如title、content),还带着Doctrine的EntityManager引用、关联实体的代理对象(哪怕是懒加载的,var_dump也会触发递归遍历,把关联对象的结构也打出来)、以及ORM维护的内部状态数据,这就是你看到“庞大响应”的根源。QueryBuilder+
HYDRATE_ARRAY的区别:
你手动指定getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY)后,Doctrine会直接把数据库查询结果映射成纯PHP数组——只保留实体的字段数据,完全丢掉ORM相关的对象结构和元数据,所以输出的格式干净又简洁。为什么其他实体用
findAll()正常?
大概率是那些实体没有复杂的关联关系(比如没有一对多、多对多的关联),或者关联的对象没有被var_dump触发加载,所以输出的内容看起来没那么夸张。而你的Article实体应该是关联了其他实体(比如分类、评论之类的),var_dump的时候递归输出了这些关联对象的全部结构,才导致内容暴增。
给你几个解决思路:
- 调试时更友好的查看数据:
别用var_dump()了,换成Symfony自带的dump()函数(需要开启调试模式),它会智能识别Doctrine实体,只显示有用的业务数据,不会递归输出ORM的内部结构,看起来清爽多了。 - 快速把实体转成数组:
如果不想写QueryBuilder,也可以用Doctrine的Serializer组件把实体对象序列化成数组,或者自己写个简单的方法提取实体的字段数据。 - 直接用
findBy()指定hydration模式:
其实findAll()本质上就是findBy([]),你可以直接这样写拿到数组格式的结果:$news = $em->getRepository('AppBundle:Article') ->findBy([], null, null, null, \Doctrine\ORM\Query::HYDRATE_ARRAY);
内容的提问来源于stack exchange,提问作者Abdullah Javar
相关产品推荐
相关产品推荐

