26
26
use Symfony \Component \Serializer \Normalizer \NormalizerInterface ;
27
27
use Symfony \Component \Serializer \Normalizer \DenormalizerInterface ;
28
28
use Symfony \Component \Serializer \Exception \LogicException ;
29
- use Symfony \Component \Serializer \Normalizer \NormalizerWithCacheableSupportResultInterface ;
29
+ use Symfony \Component \Serializer \Normalizer \CacheableSupportsMethodInterface ;
30
30
31
31
/**
32
32
* Serializer serializes and deserializes data.
@@ -55,13 +55,15 @@ class Serializer implements SerializerInterface, ContextAwareNormalizerInterface
55
55
*/
56
56
protected $ decoder ;
57
57
58
- private $ normalizerCache = array ();
59
-
60
58
/**
61
- * @var array
59
+ * @internal since Symfony 4.1
62
60
*/
63
61
protected $ normalizers = array ();
64
62
63
+ private $ cachedNormalizers ;
64
+ private $ denormalizerCache = array ();
65
+ private $ normalizerCache = array ();
66
+
65
67
public function __construct (array $ normalizers = array (), array $ encoders = array ())
66
68
{
67
69
foreach ($ normalizers as $ normalizer ) {
@@ -203,35 +205,36 @@ public function supportsDenormalization($data, $type, $format = null, array $con
203
205
*
204
206
* @return NormalizerInterface|null
205
207
*/
206
- private function getNormalizer ($ data , $ format , array $ context )
208
+ private function getNormalizer ($ data , ? string $ format , array $ context )
207
209
{
208
- $ type = \is_object ($ data ) ? 'c- ' .\get_class ($ data ) : \gettype ($ data );
209
- if (
210
- isset ($ this ->normalizerCache [$ type ][$ format ]) ||
211
- (isset ($ this ->normalizerCache [$ type ]) && \array_key_exists ($ format , $ this ->normalizerCache [$ type ]))
212
- ) {
213
- return $ this ->normalizerCache [$ type ][$ format ];
210
+ if ($ this ->cachedNormalizers !== $ this ->normalizers ) {
211
+ $ this ->cachedNormalizers = $ this ->normalizers ;
212
+ $ this ->denormalizerCache = $ this ->normalizerCache = array ();
214
213
}
214
+ $ type = \is_object ($ data ) ? \get_class ($ data ) : 'native- ' .\gettype ($ data );
215
215
216
- $ cacheable = true ;
217
- foreach ($ this ->normalizers as $ normalizer ) {
218
- if (!$ normalizer instanceof NormalizerInterface) {
219
- continue ;
220
- }
216
+ if (!isset ($ this ->normalizerCache [$ format ][$ type ])) {
217
+ $ this ->normalizerCache [$ format ][$ type ] = array ();
221
218
222
- $ cacheable = $ cacheable && $ normalizer instanceof NormalizerWithCacheableSupportResultInterface;
223
- if ($ normalizer ->supportsNormalization ($ data , $ format , $ context )) {
224
- if ($ cacheable ) {
225
- $ this ->normalizerCache [$ type ][$ format ] = $ normalizer ;
219
+ foreach ($ this ->normalizers as $ k => $ normalizer ) {
220
+ if (!$ normalizer instanceof NormalizerInterface) {
221
+ continue ;
226
222
}
227
223
228
- return $ normalizer ;
224
+ if (!$ normalizer instanceof CacheableSupportsMethodInterface) {
225
+ $ this ->normalizerCache [$ format ][$ type ][$ k ] = false ;
226
+ } elseif ($ normalizer ->supportsNormalization ($ data , $ format )) {
227
+ $ this ->normalizerCache [$ format ][$ type ][$ k ] = true ;
228
+ break ;
229
+ }
229
230
}
230
231
}
231
232
232
- if ($ cacheable ) {
233
- // allow to cache primitive types
234
- $ this ->normalizerCache [$ type ][$ format ] = null ;
233
+ foreach ($ this ->normalizerCache [$ format ][$ type ] as $ k => $ cacheable ) {
234
+ $ normalizer = $ this ->normalizers [$ k ];
235
+ if ($ cacheable || $ normalizer ->supportsNormalization ($ data , $ format , $ context )) {
236
+ return $ normalizer ;
237
+ }
235
238
}
236
239
}
237
240
@@ -245,10 +248,32 @@ private function getNormalizer($data, $format, array $context)
245
248
*
246
249
* @return DenormalizerInterface|null
247
250
*/
248
- private function getDenormalizer ($ data , $ class , $ format , array $ context )
251
+ private function getDenormalizer ($ data , string $ class , ? string $ format , array $ context )
249
252
{
250
- foreach ($ this ->normalizers as $ normalizer ) {
251
- if ($ normalizer instanceof DenormalizerInterface && $ normalizer ->supportsDenormalization ($ data , $ class , $ format , $ context )) {
253
+ if ($ this ->cachedNormalizers !== $ this ->normalizers ) {
254
+ $ this ->cachedNormalizers = $ this ->normalizers ;
255
+ $ this ->denormalizerCache = $ this ->normalizerCache = array ();
256
+ }
257
+ if (!isset ($ this ->denormalizerCache [$ format ][$ class ])) {
258
+ $ this ->denormalizerCache [$ format ][$ class ] = array ();
259
+
260
+ foreach ($ this ->normalizers as $ k => $ normalizer ) {
261
+ if (!$ normalizer instanceof DenormalizerInterface) {
262
+ continue ;
263
+ }
264
+
265
+ if (!$ normalizer instanceof CacheableSupportsMethodInterface) {
266
+ $ this ->denormalizerCache [$ format ][$ class ][$ k ] = false ;
267
+ } elseif ($ normalizer ->supportsDenormalization (null , $ class , $ format )) {
268
+ $ this ->denormalizerCache [$ format ][$ class ][$ k ] = true ;
269
+ break ;
270
+ }
271
+ }
272
+ }
273
+
274
+ foreach ($ this ->denormalizerCache [$ format ][$ class ] as $ k => $ cacheable ) {
275
+ $ normalizer = $ this ->normalizers [$ k ];
276
+ if ($ cacheable || $ normalizer ->supportsDenormalization ($ data , $ class , $ format , $ context )) {
252
277
return $ normalizer ;
253
278
}
254
279
}
0 commit comments