Use the “circular_reference_handler” key of the context instead symfony 4.2

时光怂恿深爱的人放手 提交于 2020-01-02 15:05:14

问题


I have to serialize an object and I get the ever so common "circular reference error"

I have used the old Symfony method :

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

This work but as of Symfony 4.2 I get the exception you see in the title of this question :

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

I cannot find any reference to this in the Symfony documentation concerning the Serializer.

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

Does any one know how to use this "key of context" instead of the old method?


回答1:


Unfortunately it is a bit hidden away in the docs, but you can create a class instead of using an anonymous function and then configure the serializer to use this service by default.

It is part of the configuration reference: 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'

There is no interface specified. Instead the class needs to be invokable. So in your case it could look like this:

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



回答2:


you can see a reference to this config key here : https://symfony.com/doc/current/reference/configuration/framework.html#circular-reference-handler the doc has not been updated to show usages of this config key

this config key has to be used in one of your config files (framework.yml for instance) to set the service used to handle circular references

serializer:
    circular_reference_handler: App\Service\YourCircularReferenceHandler



回答3:


An addendum to @dbrumann's answer, which very nearly worked for me. In my Symfony 4.3 application, the serializer section of the YAML requires a parent framework container. So:

# config/packages/serializer.yaml

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

And then in the reference handler:

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

To check that the config values are being loaded correctly, you can utilise the Symfony console:

$ php bin/console debug:config framework

If the config values are loaded correctly, you should see them under the appropriate section in the output.




回答4:


Alternatively, you can provide a dynamic handler in context property :

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



回答5:


In messenger configuration, You can call an object method like this:

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'}


来源:https://stackoverflow.com/questions/54645363/use-the-circular-reference-handler-key-of-the-context-instead-symfony-4-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!