-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Default Context in Serializer isn't honoured #47012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Same issue here, I just try to set: serializer:
default_context:
json_encode_options: 1024 # value of JSON_PRESERVE_ZERO_FRACTION I see that run |
Yes, that's as far as my investigation got me. I can see it's 'trying' to set the default context, but nothing appears to correctly use them. Sadly, I don't have time to investigate further, but the issue contains a bunch of easy steps for a reproduction. |
I've dump For exemple: XmlEncoder receive the defaultContext but JsonEncoder not. Inside JsonEncoder, if no $encodingImpl or $decodingImpl are passed, it create new one per default without $defaultContext class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwareInterface, SerializerAwareInterface
{
public function __construct(array $defaultContext = [])
{
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}
} class JsonEncoder implements EncoderInterface, DecoderInterface
{
public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodingImpl = null)
{
$this->encodingImpl = $encodingImpl ?? new JsonEncode();
$this->decodingImpl = $decodingImpl ?? new JsonDecode([JsonDecode::ASSOCIATIVE => true]);
}
} => I think, the problem is here: it creates new instance of Then : class JsonEncode implements EncoderInterface
{
public const OPTIONS = 'json_encode_options';
private $defaultContext = [
self::OPTIONS => 0,
];
public function __construct(array $defaultContext = [])
{
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}
} => Because the It appear we can't use
|
This behavior is still true on Symfony 6.1.3. |
i think the base problem indeed is
so the context does not get forwarded into the encode and decode classes. i see two solutions:
serializer.encoder but some new tag, as encode and decode can not be registered with the serializer) that we also find in
@nicolas-grekas which approach do you prefer? and is that a bugfix or a new feature? i could do a pull request for this. |
That's funny, because it looks like it has never worked... Think about it. It hasn't worked for years, and nobody cares. Maybe it would be better to remove this feature instead of fixing it? @dbu it's trivial to fix: ===================================================================
--- a/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php (revision 5e9664d72f1f3677796de6349ac7440fa15041a6)
+++ b/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php (date 1659725170208)
@@ -23,10 +23,10 @@
protected $encodingImpl;
protected $decodingImpl;
- public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodingImpl = null)
+ public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodingImpl = null, array $defaultContext = [])
{
- $this->encodingImpl = $encodingImpl ?? new JsonEncode();
- $this->decodingImpl = $decodingImpl ?? new JsonDecode([JsonDecode::ASSOCIATIVE => true]);
+ $this->encodingImpl = $encodingImpl ?? new JsonEncode($defaultContext);
+ $this->decodingImpl = $decodingImpl ?? new JsonDecode([JsonDecode::ASSOCIATIVE => true] + $defaultContext);
}
/**
===================================================================
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php (revision 5e9664d72f1f3677796de6349ac7440fa15041a6)
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php (date 1659725170216)
@@ -177,6 +177,7 @@
->tag('serializer.encoder')
->set('serializer.encoder.json', JsonEncoder::class)
+ ->args([null, null])
->tag('serializer.encoder')
->set('serializer.encoder.yaml', YamlEncoder::class) That's it. |
@mpiot error "Invalid constructor argument 3 for service" means that the third argument is set but the first two are not. They can be implictly set to |
@upyx thank you for the information, Iβve tried a fix like your, by passing the context as third argument but donβt understand at all why this error was triggered π |
@upyx yep exactly, that is what i formulated as variant "a)" in my comment above. i am waiting for @nicolas-grekas to tell if he prefers that or variant b). (tiny note on your patch: the symfony compiler pass uses parameter name matching, so i think you would not need to set the encode and decode parameters to null) => edit: aparently you are right, i do get an error when not setting the null parameters in #47243
well, some people seem to care, but it is rather hidden that this can be done...
on the serializer code level it worked, but you had to pass explicit encode / decode instances to the encoder class. the thing that is broken is only the symfony framework bundle configuration for those options. in the interest of least astonishment, i think its better to fix it than to remove it. |
What about adding a |
I think not. The context is bind by SerializerPass. Hovewer, it's easy to add an agrument to the constructor.
IMO, a global context for all serializers isn't a good thing. I'd rather add a service with propper settings. It as easy as set default. However, I don't know all use cases the framework, so we should ask @nicolas-grekas How to fix it... After thinking about it, @dbu @nicolas-grekas WDYT? |
imo the global context is useful. if i want all my serializers to treat e.g. JSON_PRESERVE_ZERO_FRACTION one way or the other, it makes sense to configure that globally. when i want multiple serializers with different configuration, i need to set up my own services anyways, the framework bundle only allows to configure one instance of the serializer. looking at the YamlEncoder example, i agree it would be consistent to have the default context in the JsonEncoder and merge it with the method call context when forwarding to the implementations. yaml parser has no config, yaml dumper has indentation which is not configurable for the same reason as with json encode. the json encode and decode implementations do accept a default context of their own, which we will need to keep for BC, but passing them through the method call each time seems more correct to me. |
Symfony version(s) affected
6.1.2 - 6.13
Description
The Q&A sums it up perfectly: #46117
I noticed it as I was trying to set the below, but noticed it wasn't being honored by the serializer or it's friends:
How to reproduce
Possible Solution
No response
Additional Context
No response
The text was updated successfully, but these errors were encountered: