3

我必须序列化一个对象,我得到了非常常见的“循环引用错误”

我使用了旧的 Symfony 方法:

$normalizer = new ObjectNormalizer();
// Add Circular reference handler
$normalizer->setCircularReferenceHandler(function ($object) {
    return $object->getId();
});
$normalizers = array($normalizer);
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);

这项工作,但从 Symfony 4.2 开始,我得到了你在这个问题的标题中看到的异常:

使用上下文的“circular_reference_handler”键代替 Symfony 4.2

我在有关序列化程序的 Symfony 文档中找不到对此的任何引用。

https://symfony.com/doc/current/components/serializer.html#handling-circular-references

有谁知道如何使用这个“上下文键”而不是旧方法?

4

5 回答 5

6

不幸的是,它在文档中有点隐藏,但是您可以创建一个类而不是使用匿名函数,然后将序列化程序配置为默认使用此服务。

它是配置参考的一部分:https ://symfony.com/doc/current/reference/configuration/framework.html#reference-serializer-circular-reference-handler

# config/packages/serializer.yaml

serializer:
    circular_reference_handler: 'App\Serializer\MyCircularReferenceHandler'

没有指定接口。相反,该类需要是可调用的。因此,在您的情况下,它可能如下所示:

class MyCircularReferenceHandler
{
    public function __invoke($object)
    {
        return $object->id;
    }
}
于 2019-02-12T08:30:22.347 回答
1

@dbrumann 答案的附录,它几乎对我有用。在我的 Symfony 4.3 应用程序中,serializerYAML 的部分需要一个父framework容器。所以:

# config/packages/serializer.yaml

framework:
    serializer:
        circular_reference_handler: 'App\Serializer\MyCircularReferenceHandler'

然后在参考处理程序中:

class MyCircularReferenceHandler {
    public function __invoke($object) {
        return $object->id;
    }
}

要检查配置值是否正确加载,您可以使用 Symfony 控制台:

$ php bin/console debug:config framework

如果正确加载了配置值,您应该在输出的相应部分下看到它们。

于 2019-09-09T16:46:59.030 回答
1

您可以在此处看到对此配置键的引用:https ://symfony.com/doc/current/reference/configuration/framework.html#circular-reference-handler该文档尚未更新以显示此配置键的用法

必须在您的配置文件之一(例如framework.yml)中使用此配置键来设置用于处理循环引用的服务

serializer:
    circular_reference_handler: App\Service\YourCircularReferenceHandler
于 2019-02-12T08:30:09.390 回答
0

或者,您可以在上下文属性中提供动态处理程序:

public function normalize($user, $format = null, array $context = [])
{
    // Handle circular references
    // DEPRECATED in sf 4.2 : 
    // $this->normalizer->setCircularReferenceHandler(function ($object) {return $object->getId();});

    // Good way in sf > 4.2
    $context['circular_reference_handler'] = function ($object) {return $object->getId();};
    // Return data
    $data = $this->normalizer->normalize($user, $format, $context);
}
于 2019-07-22T09:26:15.227 回答
0

在 messenger 配置中,您可以像这样调用对象方法:

class CircularReferenceHandler
{
    public function handle($object, string $format, array $context)
    {
        return $object->getId();
    }
}
# config/package/messenger.yaml
framework:
  messenger:
    serializer:
      default_serializer: messenger.transport.symfony_serializer
      symfony_serializer:
        format: json
        context: {circular_reference_handler: 'App\application\Helpers\CircularReferenceHandler::handle'}
于 2019-11-26T10:06:28.370 回答