简体   繁体   English

如何在Symfony中使用循环引用处理程序将其序列化为json?

[英]How can I seralize to json with circular reference handler in Symfony?

I want to serialize my database table into a json file: 我想将数据库表序列化为json文件:

$table = $this->em->getRepository($EntityName)->findAll();

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

$encoders = [new JsonEncoder()]; 
$normalizers = [new DateTimeNormalizer(array('datetime_format' => 'd.m.Y')), new ObjectNormalizer($classMetadataFactory)];
$serializer = new Serializer($normalizers, $encoders);

$context = [
    'circular_reference_handler' => function ($object) {
        return $object->getId();
    },
    'circular_reference_limit' => 0,
];

$data = $serializer->serialize($table, 'json', $context);

But I have some problems with the performance. 但是我的表现有些问题。 My page loads really slow, for several seconds, and then I get a blank page. 我的页面加载速度非常慢,持续了几秒钟,然后出现空白页面。

I use this to serialize my objects and send a JsonResponse 我用这个序列化我的对象和发送JsonResponse

<?php
namespace App\Services\Api\Serializer;

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Doctrine\Common\Annotations\AnnotationReader;

class ObjectSerializer
{
    private $object;
    private $specifics_attributes;

    public function __construct($object, Array $groups = ['default'], Array $specifics_attributes = null)
    {
        $this->object = $object;
        $this->groups = $groups;
        $this->specifics_attributes = $specifics_attributes;
    }

    public function serializeObject(): ?Array
    {
        $object = $this->object;

        $defaultContext = [
            AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
                return $object;
            },
        ];

        $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
        $normalizer = [new DateTimeNormalizer('Y-m-d'), new ObjectNormalizer($classMetadataFactory, null, null, null, null, null, $defaultContext)];
        $serializer = new Serializer($normalizer);

        return $serializer->normalize($object, null, $this->normalizerFilters());
    }

    private function normalizerFilters():Array
    {
        $groups = $this->groups;
        $specifics_attributes = $this->specifics_attributes;

        $normalizer_filter = [
            'groups' => $groups,
        ];

        if ($specifics_attributes) {
            $normalizer_filter['attributes'] = $specifics_attributes;
        }

        return $normalizer_filter;
    }
}

Then in the controller or another service we can use that like this 然后在控制器或其他服务中,我们可以像这样使用

use App\Services\Api\Serializer\ObjectSerializer;

/* Some codes */

$objectSerializer = new ObjectSerializer($objects, ['my_custom_attributes_groupe']);

return new JsonResponse([
    'status' => 'success',
    'MyEntityName' => $objectSerializer->serializeObject(),
], JsonResponse::HTTP_OK);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM