2016-06-28 81 views
3

我有一个简单的实体类:Symfony的序列化主义实体

<?php 
namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 


/** 
* @ORM\Entity(repositoryClass="CompanyUserRepository") 
* @ORM\Table(name="company_users") 
*/ 
class CompanyUser 
{ 
/** 
* @ORM\Column(type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @ORM\Column(type="string", length=100) 
*/ 
private $firstName; 

/** 
* @ORM\Column(type="string", length=100) 
*/ 
private $lastName ; 

/** 
* @ORM\OneToMany(targetEntity="Score", mappedBy="user") 
*/ 
private $scores; 
/** 
* Constructor 
*/ 
public function __construct() 
{ 
    $this->scores = new ArrayCollection(); 
} 

/** 
* Get id 
* 
* @return integer 
*/ 
public function getId() 
{ 
    return $this->id; 
} 

/** 
* Set firstName 
* 
* @param string $firstName 
* 
* @return CompanyUser 
*/ 
public function setFirstName($firstName) 
{ 
    $this->firstName = $firstName; 

    return $this; 
} 

/** 
* Get firstName 
* 
* @return string 
*/ 
public function getFirstName() 
{ 
    return $this->firstName; 
} 

/** 
* Set lastName 
* 
* @param string $lastName 
* 
* @return CompanyUser 
*/ 
public function setLastName($lastName) 
{ 
    $this->lastName = $lastName; 

    return $this; 
} 

/** 
* Get lastName 
* 
* @return string 
*/ 
public function getLastName() 
{ 
    return $this->lastName; 
} 

/** 
* Add score 
* 
* @param \AppBundle\Entity\Score $score 
* 
* @return CompanyUser 
*/ 
public function addScore(\AppBundle\Entity\Score $score) 
{ 
    $this->scores[] = $score; 

    return $this; 
} 

/** 
* Remove score 
* 
* @param \AppBundle\Entity\Score $score 
*/ 
public function removeScore(\AppBundle\Entity\Score $score) 
{ 
    $this->scores->removeElement($score); 
} 

/** 
* Get scores 
* 
* @return \Doctrine\Common\Collections\Collection 
*/ 
public function getScores() 
{ 
    return $this->scores; 
} 

}

问题是当我试图让所有的用户和JSON序列化他们:

/** 
* @Route("/api/getUsers", name="getUsers") 
*/ 
public function getUsers(Request $request){ 
    $users = $this->getDoctrine() 
    ->getRepository('AppBundle:CompanyUser') 
    ->findAll(); 

    $serializer = $this->get('serializer'); 
    $data = $serializer->serialize($users, 'json'); 

    return new Response($users); 
} 

我得到已检测到循环参考(配置的限制:1)。 当我删除getScores getter时,一切正常。我只需要获得id,firstName和lastName。有没有办法不序列化其他对象?

+1

对可能序列化的对象实现\ Serializable接口是一种很好的做法。考虑到这一点。 – Muriano

回答

4

那么,在使用关系序列化实体时,处理circular references是很常见的事情。

解决方案没有。 1:实现可序列化的接口并使关系属性不是序列化/反序列化(大多数情况下,这是一个有效的解决方案)

解决方案编号2:此规范化器的setCircularReferenceLimit()方法设置在将其考虑为循环引用之前将序列化相同对象的次数。它的默认值是1,因此,呼吁serialize()方法之前,这样做:

public function getUsers(Request $request){ 
    $users = $this->getDoctrine() 
    ->getRepository('AppBundle:CompanyUser') 
    ->findAll(); 

    $serializer = $this->get('serializer'); 
    $serializer->setCircularReferenceLimit(2); // Change this with a proper value for your case 
    $data = $serializer->serialize($users, 'json'); 

    return new Response($data); 
} 

**** ****更新

正如@Derek说,在他的评论中,解决方案没有。 2在某些Symfony版本中可能无效。然后,你可以尝试这种方式设置一个处理循环引用:

$encoder = new JsonEncoder(); 
$normalizer = new ObjectNormalizer(); 

$normalizer->setCircularReferenceHandler(function ($object) { 
    return $object->getName(); // Change this to a valid method of your object 
}); 

$serializer = new Serializer(array($normalizer), array($encoder)); 
var_dump($serializer->serialize($org, 'json'));  

这应该回到你的实体值,而不是遍历关系。

+0

您的解决方案没有。 2不起作用。 setCircularReferenceLimit()方法不属于Serializer类,而属于AbstractNormalizer。你的代码(至少在Symfony 2.8中)会引发一个致命的错误。由于getNormalizer()方法是私有的,因此我无法找到从序列化程序服务获取此规范化程序的方法... – Derek

+0

getNormalizer()方法是私有的,因此无法使用它(并且它需要2个参数) 。看来标准器只能在将其注入到串行器之前进行定制... – Derek

+0

对于最后的评论@Derek,我很匆忙。我已经更新了我的回复,并添加了处理此错误的新方法。 – Muriano