为什么在设置setCircularReferenceHandler
回调时,我的回复会返回“空白”?
编辑:
看起来它什么都不返回,但确实将标题设置为500 Internal Server Error
。这是令人困惑的,因为Symfony应该发送关于错误的某种错误响应?
我在try / catch中包装$json = $serializer->serialize($data, 'json');
但是没有抛出显式错误,因此没有捕获任何内容。任何想法都会非常有用。
查询实体媒体时,我得到一个空白的回复。实体媒体(与Doctrine)映射到实体作者。在链接时,尝试序列化时可能会出现无限循环。
我原本希望使用循环引用处理程序,我可以避免这种情况,但它不起作用。
当我不设置循环引用处理程序时,这是我得到的错误:
在序列化类“Proxies__CG __ \ AppBundle \ Entity \ Author \ Author”(配置限制:1)(500内部服务器错误)
的对象时,检测到循环引用
现在此错误 完全预期 ,因为我的实体作者在最初查询媒体时指向实体媒体(Media -> Author -> Media
)
class Author implements JsonSerializable {
//Properties, Getters and setters here
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
function jsonSerialize()
{
return [
"title" => $this->getTitle(),
"id" => $this->getId(),
"firstname" => $this->getFirstname(),
"lastname" => $this->getLastname(),
//This is the problem right here. Circular reference.
"medias" => $this->getAuthorsMedia()->map(function($object){
return $object->getMedia();
})
];
}
}
我的实体实现了JsonSerializable
接口,因此我定义了返回的属性(JsonSerializeNormalizer
所需的属性)。当我删除作者类中的“medias”属性 , 一切正常 时,这完全可以 。
以下是我将serliazer与规范化器一起使用的方法。
/**
* @Route("/media")
* Class MediaController
* @package BackBundle\Controller\Media
*/
class MediaController extends Controller
{
/**
* @Route("")
* @Method({"GET"})
*/
public function listAction(){
/** @var MediaService $mediaS */
$mediaS= $this->get("app.media");
/** @var array $data */
$data = $mediaS->getAll();
$normalizer = new JsonSerializableNormalizer();
$normalizer->setCircularReferenceLimit(1);
$normalizer->setCircularReferenceHandler(function($object){
return $object->getId();
});
$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$json = $serializer->serialize($data, 'json');
return new Response($json);
}
}
答案 0 :(得分:1)
我试图重现你的错误,对我来说一切都按预期工作(参见下面的代码示例)。
所以,你的setCircularReferenceHandler()工作正常。
也许尝试运行我的代码,并逐步更新它与真实实体和数据源,直到看到导致错误的原因。
测试(而不是您的控制器):
class SerializerTest extends \PHPUnit\Framework\TestCase
{
public function testIndex()
{
$media = new Media();
$author = new Author();
$media->setAuthor($author);
$author->addMedia($media);
$data = [$media];
$normalizer = new JsonSerializableNormalizer();
$normalizer->setCircularReferenceLimit(1);
$normalizer->setCircularReferenceHandler(function($object){
/** @var Media $object */
return $object->getId();
});
$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$json = $serializer->serialize($data, 'json');
$this->assertJson($json);
$this->assertCount(1, json_decode($json));
}
}
媒体实体
class Media implements \JsonSerializable
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Author
*
* @ORM\ManyToOne(targetEntity="Author", inversedBy="medias")
* @ORM\JoinColumn(name="author_id", referencedColumnName="id")
*/
private $author;
/**
* {@inheritdoc}
*/
function jsonSerialize()
{
return [
"id" => $this->getId(),
"author" => $this->getAuthor(),
];
}
//todo: here getter and setters, generated by doctrine
}
作者实体
class Author implements \JsonSerializable
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Media[]
*
* @ORM\OneToMany(targetEntity="Media", mappedBy="author")
*/
private $medias;
/**
* {@inheritdoc}
*/
function jsonSerialize()
{
return [
"id" => $this->getId(),
"medias" => $this->getMedias(),
];
}
//todo: here getter and setters, generated by doctrine
}