使用 setCircularReferenceHandler 时使用 Normalizer returns 的序列化器什么都没有
Serializer using Normalizer returns nothing when using setCircularReferenceHandler
问题:
为什么当我设置 setCircularReferenceHandler
回调时我的响应 return "blank"?
编辑:
看起来 return 没什么,但确实将 header 设置为 500 Internal Server Error
。这令人困惑,因为 Symfony 应该发送某种关于错误的错误响应?
我将 $json = $serializer->serialize($data, 'json');
包装在 try/catch 中,但没有抛出明确的错误,因此没有捕获任何内容。任何想法都会很有帮助。
上下文:
查询实体媒体时,我得到空白响应。实体媒体被映射(使用 Doctrine)到实体作者。由于它们是链接的,因此在尝试序列化时可能会出现无限循环。
我曾希望使用循环引用处理程序可以避免这种情况,但它不起作用。
错误:
这是我在 NOT 设置循环引用处理程序时遇到的错误:
A circular reference has been detected when serializing the object of class "Proxies__CG__\AppBundle\Entity\Author\Author" (configured limit: 1) (500 Internal Server Error)
现在这个错误是完全预期的,因为我的实体作者在最初查询媒体时指向实体媒体(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
接口,所以我定义了哪些属性是 returned(这是 JsonSerializeNormalizer
所要求的)。当我删除作者 class、[=54= 中的 "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);
}
}
我试图重现你的错误,对我来说一切都按预期工作(见下面的代码示例)。
所以,你的 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
}
问题:
为什么当我设置 setCircularReferenceHandler
回调时我的响应 return "blank"?
编辑:
看起来 return 没什么,但确实将 header 设置为 500 Internal Server Error
。这令人困惑,因为 Symfony 应该发送某种关于错误的错误响应?
我将 $json = $serializer->serialize($data, 'json');
包装在 try/catch 中,但没有抛出明确的错误,因此没有捕获任何内容。任何想法都会很有帮助。
上下文:
查询实体媒体时,我得到空白响应。实体媒体被映射(使用 Doctrine)到实体作者。由于它们是链接的,因此在尝试序列化时可能会出现无限循环。
我曾希望使用循环引用处理程序可以避免这种情况,但它不起作用。
错误:
这是我在 NOT 设置循环引用处理程序时遇到的错误:
A circular reference has been detected when serializing the object of class "Proxies__CG__\AppBundle\Entity\Author\Author" (configured limit: 1) (500 Internal Server Error)
现在这个错误是完全预期的,因为我的实体作者在最初查询媒体时指向实体媒体(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
接口,所以我定义了哪些属性是 returned(这是 JsonSerializeNormalizer
所要求的)。当我删除作者 class、[=54= 中的 "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);
}
}
我试图重现你的错误,对我来说一切都按预期工作(见下面的代码示例)。
所以,你的 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
}