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

我使用了旧的 Symfony 方法:

1
2
3
4
5
6
7
8
$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 开始,我得到了你在这个问题的标题中看到的异常:

use the”circular_reference_handler” key of the context instead Symfony 4.2

我在 Symfony 文档中找不到关于序列化器的任何引用。

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

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


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

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

1
2
3
4
# config/packages/serializer.yaml

serializer :
    circular_reference_handler : ‘App\\Serializer\\MyCircularReferenceHandler’

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

1
2
3
4
5
6
7
class MyCircularReferenceHandler
{
    public function __invoke ( $object )
    {
        return $object -> id ;
    }
}



相关讨论

  • 谢谢回复。但是我应该如何使用这种方法?我只是一起放弃了整个 $normalizer->setCircularReferenceHandler 吗?
  • @DennisdeBest 是的,您可以删除 setCircularReferenceHandler 。配置设置处理程序,如果检测到循环引用,将自动调用该处理程序。
  • 好的,我对将 circular_reference_handler 键放在哪里有点困惑原来它在 framework.yaml 下的 framework:serializer:circular_reference_handler 这个函数现在被正确调用了。这给我留下了最大的嵌套错误,但这是另一个主题。谢谢你的帮助


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

1
2
3
4
5
# config/packages/serializer.yaml

framework :
    serializer :
        circular_reference_handler : ‘App\\Serializer\\MyCircularReferenceHandler’

然后在引用处理程序中:

1
2
3
4
5
class MyCircularReferenceHandler {
    public function __invoke ( $object ) {
        return $object -> id ;
    }
}

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

1 $ php bin /console debug :config framework

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


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

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

1
2
serializer :
    circular_reference_handler : App\\Service\\YourCircularReferenceHandler

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

1
2
3
4
5
6
7
class CircularReferenceHandler
{
    public function handle ( $object , string $format , array $context )
    {
        return $object -> getId ( ) ;
    }
}

1
2
3
4
5
6
7
8
# 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’ }

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

1
2
3
4
5
6
7
8
9
10
11
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 ) ;
}


声明:本站(华域联盟www.cnhackhy.com)所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。