Symfony 3.2检测到循环引用(配置限制:1)

Cha*_*mae 14 serializer symfony symfony-3.2

我的项目中有这两个实体

class PoliceGroupe
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="code", type="string", length=50)
     */
    private $code;

    /**
     * @ORM\ManyToMany(targetEntity="PointVente", inversedBy="policegroupe")
     * @ORM\JoinTable(name="police_groupe_point_vente",
     *      joinColumns={@ORM\JoinColumn(name="police_groupe_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="point_vente_id", referencedColumnName="id")}
     *      )
     */
    private $pointVente;
    /**
     * Constructor
     */
    public function __construct($produit)
    {
       $this->pointVente = new \Doctrine\Common\Collections\ArrayCollection();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的另一个实体

class PointVente
{
    /**
     * @var string
     *
     * @ORM\Column(name="abb", type="string", length=50)
     */
    private $abb;

    /**
     * @var string
     *
     * @ORM\Column(name="libelle", type="string", length=255)
     */
    private $libelle;

    /**
     *
     * @ORM\ManyToMany(targetEntity="PoliceGroupe", mappedBy="pointVente")
     */
    private $policegroupe;
    }
Run Code Online (Sandbox Code Playgroud)

我试图在我的控制器中运行此代码

$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$em = $this->getDoctrine()->getManager();
$data = $request->get('data');
$policegroupe=$em->getRepository('StatBundle:PoliceGroupe')->findOneBy(array('id' => $data));
$pointventes = $policegroupe->getPointVente();
$jsonContent = $serializer->serialize($pointventes, 'json');
return new JsonResponse( array('pointventes'=>$jsonContent) );
Run Code Online (Sandbox Code Playgroud)

但我得到了这个例外

Symfony\Component\Serializer\Exception\CircularReferenceException: A circular reference has been detected (configured limit: 1).
    at n/a
        in C:\wamp\www\Sys\vendor\symfony\symfony\src\Symfony\Component\Serializer\Normalizer\AbstractNormalizer.php line 194
Run Code Online (Sandbox Code Playgroud)

我根据学说注释映射了我的实体.我错过了什么吗?

Ila*_*sta 29

使用该useCircularReferenceLimit方法.例如:

$normalizer = new ObjectNormalizer();
$normalizer->setCircularReferenceLimit(2);
// Add Circular reference handler
$normalizer->setCircularReferenceHandler(function ($object) {
    return $object->getId();
});
$normalizers = array($normalizer);
$serializer = new Serializer($normalizers, $encoders);
Run Code Online (Sandbox Code Playgroud)

原因是当您尝试序列化它们时,实体中的循环引用会导致一些问题.该方法的作用是定义序列化层次结构的最大深度.

编辑:添加循环引用处理程序(已检测到循环引用(配置限制:1)Serializer SYMFONY)

更新(Symfony 4.2)

circular_reference_limit并且circular_reference_handler不赞成使用上下文中的以下键:idsetCircularReferenceHandler.所以:

// Tip : Inject SerializerInterface $serializer in the controller method
// and avoid these 3 lines of instanciation/configuration
$encoders = [new JsonEncoder()]; // If no need for XmlEncoder
$normalizers = [new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders);

// Serialize your object in Json
$jsonObject = $serializer->serialize($objectToSerialize, 'json', [
    'circular_reference_handler' => function ($object) {
        return $object->getId();
    }
]);

// For instance, return a Response with encoded Json
return new Response($jsonObject, 200, ['Content-Type' => 'application/json']);
Run Code Online (Sandbox Code Playgroud)

请参阅:https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php#L111

  • 我添加了这个,现在它正在工作`$ normalizer-> setCircularReferenceLimit(2); $ normalizer-> setCircularReferenceHandler(function($ object){return $ object-> getId();});` (2认同)
  • 我得到了相同的解决方案,并更新了帖子。好! (2认同)

小智 6

最好的方法是使用useCircularReferenceLimit方法。因为在这篇文章中已经清楚地解释了。

但我们还有另一种选择。作为一种选择,有一种方法可以忽略原始对象的属性。如果我们在序列化对象中绝对不需要它,我们可以忽略它。这种方案的优点是序列化后的对象更小更容易阅读,缺点是我们将不再引用被忽略的属性。

Symfony 2.3 - 4.1

要删除这些属性,请使用规范化器定义上的 setIgnoredAttributes() 方法:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(array('age'));
$encoder = new JsonEncoder();

$serializer = new Serializer(array($normalizer), array($encoder));
$serializer->serialize($person, 'json'); // Output: {"name":"foo","sportsperson":false}
Run Code Online (Sandbox Code Playgroud)

setIgnoredAttributes()方法是在 Symfony 2.3 中引入的。

在 Symfony 2.7 之前,只有在序列化时才会忽略属性。从 Symfony 2.7 开始,反序列化时它们也会被忽略。

Symfony 4.2 - 5.0

setIgnoredAttributes()在于使用作为替代ignored_attributes选项方法中的Symfony 4.2被弃用。

要删除这些属性,请通过ignored_attributes所需序列化程序方法的上下文参数中的键提供一个数组:

use Acme\Person;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

$person = new Person();
$person->setName('foo');
$person->setAge(99);

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

$serializer = new Serializer([$normalizer], [$encoder]);
$serializer->serialize($person, 'json', ['ignored_attributes' => ['age']]); // Output: {"name":"foo"}
Run Code Online (Sandbox Code Playgroud)

在我的 Symfony 3.4 项目中,我混合使用了这两种方法setIgnoredAttributes()setCircularReferenceLimit()并且效果很好。

来源:https : //symfony.com/doc/3.4/components/serializer.html