【问题标题】:How can I seralize to json with circular reference handler in Symfony?如何在 Symfony 中使用循环引用处理程序序列化为 json?
【发布时间】:2019-09-05 07:15:54
【问题描述】:

我想把我的数据库表序列化成一个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);

但是我的性能有一些问题。我的页面加载速度非常慢,持续了几秒钟,然后我得到一个空白页面。

【问题讨论】:

  • 为什么将circular_reference_limit 设置为0
  • @yivi 我尝试将其设置为1,但问题是一样的
  • 但是为什么要设置为0呢?您希望完成什么?

标签: php symfony serialization


【解决方案1】:

我用它来序列化我的对象并发送一个 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;
    }
}

然后在控制器或其他服务中我们可以像这样使用它

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2014-05-09
    • 1970-01-01
    相关资源
    最近更新 更多