From c1e850fe834e01d32bbfab42cc5276b75422bdea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 25 Apr 2018 17:25:58 +0200 Subject: [PATCH 1/2] [Serializer] Cache the normalizer to use when possible --- .../Normalizer/AbstractObjectNormalizer.php | 2 +- .../ConstraintViolationListNormalizer.php | 2 +- .../Normalizer/CustomNormalizer.php | 2 +- .../Normalizer/DataUriNormalizer.php | 2 +- .../Normalizer/DateIntervalNormalizer.php | 2 +- .../Normalizer/DateTimeNormalizer.php | 2 +- .../Normalizer/JsonSerializableNormalizer.php | 2 +- ...zerWithCacheableSupportResultInterface.php | 21 ++++++++++++++ .../Component/Serializer/Serializer.php | 28 ++++++++++++++++++- 9 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index abac37770e333..d9de481d73876 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -30,7 +30,7 @@ * * @author Kévin Dunglas */ -abstract class AbstractObjectNormalizer extends AbstractNormalizer +abstract class AbstractObjectNormalizer extends AbstractNormalizer implements NormalizerWithCacheableSupportResultInterface { const ENABLE_MAX_DEPTH = 'enable_max_depth'; const DEPTH_KEY_PATTERN = 'depth_%s::%s'; diff --git a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php index 68a4cb9213279..9ac604eca33c6 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php @@ -22,7 +22,7 @@ * @author Grégoire Pineau * @author Kévin Dunglas */ -class ConstraintViolationListNormalizer implements NormalizerInterface +class ConstraintViolationListNormalizer implements NormalizerInterface, NormalizerWithCacheableSupportResultInterface { /** * {@inheritdoc} diff --git a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php index 6a15d8da90270..7b54ff2d7f3ac 100644 --- a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php @@ -17,7 +17,7 @@ /** * @author Jordi Boggiano */ -class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface +class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface, NormalizerWithCacheableSupportResultInterface { use ObjectToPopulateTrait; use SerializerAwareTrait; diff --git a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php index 995bdf1441776..499e5f18fbf74 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php @@ -23,7 +23,7 @@ * * @author Kévin Dunglas */ -class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface +class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerWithCacheableSupportResultInterface { private static $supportedTypes = array( \SplFileInfo::class => true, diff --git a/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php index 7ab102ed7a9ec..4f80ced0bc60e 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php @@ -20,7 +20,7 @@ * * @author Jérôme Parmentier */ -class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterface +class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerWithCacheableSupportResultInterface { const FORMAT_KEY = 'dateinterval_format'; diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 3dd94e07e029b..b38f2efa208fa 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -20,7 +20,7 @@ * * @author Kévin Dunglas */ -class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface +class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerWithCacheableSupportResultInterface { const FORMAT_KEY = 'datetime_format'; const TIMEZONE_KEY = 'datetime_timezone'; diff --git a/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php index 27ccf8023cba3..6ba4cee1c4e6c 100644 --- a/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php @@ -19,7 +19,7 @@ * * @author Fred Cox */ -class JsonSerializableNormalizer extends AbstractNormalizer +class JsonSerializableNormalizer extends AbstractNormalizer implements NormalizerWithCacheableSupportResultInterface { /** * {@inheritdoc} diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php new file mode 100644 index 0000000000000..7b8eabc400948 --- /dev/null +++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +/** + * "supportsNormalization()" methods of normalizers implementing this interface have a cacheable return. + * + * @author Kévin Dunglas + */ +interface NormalizerWithCacheableSupportResultInterface +{ +} diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 1a7087042567a..5601182d1389c 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -26,6 +26,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Exception\LogicException; +use Symfony\Component\Serializer\Normalizer\NormalizerWithCacheableSupportResultInterface; /** * Serializer serializes and deserializes data. @@ -54,6 +55,8 @@ class Serializer implements SerializerInterface, ContextAwareNormalizerInterface */ protected $decoder; + private $normalizerCache = array(); + /** * @var array */ @@ -202,11 +205,34 @@ public function supportsDenormalization($data, $type, $format = null, array $con */ private function getNormalizer($data, $format, array $context) { + $type = \is_object($data) ? 'c-'.\get_class($data) : \gettype($data); + if ( + isset($this->normalizerCache[$type][$format]) || + (isset($this->normalizerCache[$type]) && \array_key_exists($format, $this->normalizerCache[$type])) + ) { + return $this->normalizerCache[$type][$format]; + } + + $cacheable = true; foreach ($this->normalizers as $normalizer) { - if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format, $context)) { + if (!$normalizer instanceof NormalizerInterface) { + continue; + } + + $cacheable = $cacheable && $normalizer instanceof NormalizerWithCacheableSupportResultInterface; + if ($normalizer->supportsNormalization($data, $format, $context)) { + if ($cacheable) { + $this->normalizerCache[$type][$format] = $normalizer; + } + return $normalizer; } } + + if ($cacheable) { + // allow to cache primitive types + $this->normalizerCache[$type][$format] = null; + } } /** From 16f8a1381018cbd0bbcc47d589921ac9562b131d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 27 Apr 2018 14:29:13 +0200 Subject: [PATCH 2/2] [Serializer] Generalize caching support a bit --- src/Symfony/Component/Serializer/CHANGELOG.md | 2 + .../Normalizer/AbstractObjectNormalizer.php | 9 +-- ...p => CacheableSupportsMethodInterface.php} | 8 +- .../ConstraintViolationListNormalizer.php | 2 +- .../Normalizer/CustomNormalizer.php | 14 +--- .../Normalizer/DataUriNormalizer.php | 2 +- .../Normalizer/DateIntervalNormalizer.php | 2 +- .../Normalizer/DateTimeNormalizer.php | 2 +- .../Normalizer/GetSetMethodNormalizer.php | 5 +- .../Normalizer/JsonSerializableNormalizer.php | 2 +- .../Normalizer/PropertyNormalizer.php | 6 +- .../Component/Serializer/Serializer.php | 81 ++++++++++++------- 12 files changed, 75 insertions(+), 60 deletions(-) rename src/Symfony/Component/Serializer/Normalizer/{NormalizerWithCacheableSupportResultInterface.php => CacheableSupportsMethodInterface.php} (54%) diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 9c1dccb5d9fe9..983bb9f5a0654 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGELOG 4.1.0 ----- +* added `CacheableSupportsMethodInterface` for normalizers and denormalizers that use + only the type and the format in their `supports*()` methods * added `MissingConstructorArgumentsException` new exception for deserialization failure of objects that needs data insertion in constructor * added an optional `default_constructor_arguments` option of context to specify a default data in diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index d9de481d73876..a7055498d5ff8 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -30,7 +30,7 @@ * * @author Kévin Dunglas */ -abstract class AbstractObjectNormalizer extends AbstractNormalizer implements NormalizerWithCacheableSupportResultInterface +abstract class AbstractObjectNormalizer extends AbstractNormalizer implements CacheableSupportsMethodInterface { const ENABLE_MAX_DEPTH = 'enable_max_depth'; const DEPTH_KEY_PATTERN = 'depth_%s::%s'; @@ -38,7 +38,6 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer implements No private $propertyTypeExtractor; private $attributesCache = array(); - private $cache = array(); /** * @var callable|null @@ -225,11 +224,7 @@ public function setMaxDepthHandler(?callable $handler): void */ public function supportsDenormalization($data, $type, $format = null) { - if (!isset($this->cache[$type])) { - $this->cache[$type] = class_exists($type) || (interface_exists($type) && null !== $this->classDiscriminatorResolver && null !== $this->classDiscriminatorResolver->getMappingForClass($type)); - } - - return $this->cache[$type]; + return \class_exists($type) || (\interface_exists($type, false) && $this->classDiscriminatorResolver && null !== $this->classDiscriminatorResolver->getMappingForClass($type)); } /** diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php b/src/Symfony/Component/Serializer/Normalizer/CacheableSupportsMethodInterface.php similarity index 54% rename from src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php rename to src/Symfony/Component/Serializer/Normalizer/CacheableSupportsMethodInterface.php index 7b8eabc400948..f3b50be7cdcd3 100644 --- a/src/Symfony/Component/Serializer/Normalizer/NormalizerWithCacheableSupportResultInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/CacheableSupportsMethodInterface.php @@ -12,10 +12,14 @@ namespace Symfony\Component\Serializer\Normalizer; /** - * "supportsNormalization()" methods of normalizers implementing this interface have a cacheable return. + * Marker interface for normalizers and denormalizers that use + * only the type and the format in their supports*() methods. + * + * By implementing this interface, the return value of the + * supports*() methods will be cached by type and format. * * @author Kévin Dunglas */ -interface NormalizerWithCacheableSupportResultInterface +interface CacheableSupportsMethodInterface { } diff --git a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php index 9ac604eca33c6..cf1c6616fa58c 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php @@ -22,7 +22,7 @@ * @author Grégoire Pineau * @author Kévin Dunglas */ -class ConstraintViolationListNormalizer implements NormalizerInterface, NormalizerWithCacheableSupportResultInterface +class ConstraintViolationListNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface { /** * {@inheritdoc} diff --git a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php index 7b54ff2d7f3ac..87ad14102281f 100644 --- a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php @@ -17,13 +17,11 @@ /** * @author Jordi Boggiano */ -class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface, NormalizerWithCacheableSupportResultInterface +class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface, CacheableSupportsMethodInterface { use ObjectToPopulateTrait; use SerializerAwareTrait; - private $cache = array(); - /** * {@inheritdoc} */ @@ -67,14 +65,6 @@ public function supportsNormalization($data, $format = null) */ public function supportsDenormalization($data, $type, $format = null) { - if (isset($this->cache[$type])) { - return $this->cache[$type]; - } - - if (!class_exists($type)) { - return $this->cache[$type] = false; - } - - return $this->cache[$type] = is_subclass_of($type, 'Symfony\Component\Serializer\Normalizer\DenormalizableInterface'); + return \is_subclass_of($type, DenormalizableInterface::class); } } diff --git a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php index 499e5f18fbf74..9b637a269ca33 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php @@ -23,7 +23,7 @@ * * @author Kévin Dunglas */ -class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerWithCacheableSupportResultInterface +class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface { private static $supportedTypes = array( \SplFileInfo::class => true, diff --git a/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php index 4f80ced0bc60e..ee30dddcada6d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php @@ -20,7 +20,7 @@ * * @author Jérôme Parmentier */ -class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerWithCacheableSupportResultInterface +class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface { const FORMAT_KEY = 'dateinterval_format'; diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index b38f2efa208fa..aced67e37a881 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -20,7 +20,7 @@ * * @author Kévin Dunglas */ -class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerWithCacheableSupportResultInterface +class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface { const FORMAT_KEY = 'datetime_format'; const TIMEZONE_KEY = 'datetime_timezone'; diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index a6b8327be1ff9..4df997cbbcf39 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -35,14 +35,13 @@ class GetSetMethodNormalizer extends AbstractObjectNormalizer { private static $setterAccessibleCache = array(); - private $cache = array(); /** * {@inheritdoc} */ public function supportsNormalization($data, $format = null) { - return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type)); + return parent::supportsNormalization($data, $format) && $this->supports(\get_class($data)); } /** @@ -50,7 +49,7 @@ public function supportsNormalization($data, $format = null) */ public function supportsDenormalization($data, $type, $format = null) { - return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type)); + return parent::supportsDenormalization($data, $type, $format) && $this->supports($type); } /** diff --git a/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php index 6ba4cee1c4e6c..912546b4b03c9 100644 --- a/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/JsonSerializableNormalizer.php @@ -19,7 +19,7 @@ * * @author Fred Cox */ -class JsonSerializableNormalizer extends AbstractNormalizer implements NormalizerWithCacheableSupportResultInterface +class JsonSerializableNormalizer extends AbstractNormalizer implements CacheableSupportsMethodInterface { /** * {@inheritdoc} diff --git a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php index fe0d3521e890e..5690d07d461ea 100644 --- a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php @@ -30,14 +30,12 @@ */ class PropertyNormalizer extends AbstractObjectNormalizer { - private $cache = array(); - /** * {@inheritdoc} */ public function supportsNormalization($data, $format = null) { - return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type)); + return parent::supportsNormalization($data, $format) && $this->supports(\get_class($data)); } /** @@ -45,7 +43,7 @@ public function supportsNormalization($data, $format = null) */ public function supportsDenormalization($data, $type, $format = null) { - return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type)); + return parent::supportsDenormalization($data, $type, $format) && $this->supports($type); } /** diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 5601182d1389c..488b269d4fa6d 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -26,7 +26,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Exception\LogicException; -use Symfony\Component\Serializer\Normalizer\NormalizerWithCacheableSupportResultInterface; +use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface; /** * Serializer serializes and deserializes data. @@ -55,13 +55,15 @@ class Serializer implements SerializerInterface, ContextAwareNormalizerInterface */ protected $decoder; - private $normalizerCache = array(); - /** - * @var array + * @internal since Symfony 4.1 */ protected $normalizers = array(); + private $cachedNormalizers; + private $denormalizerCache = array(); + private $normalizerCache = array(); + public function __construct(array $normalizers = array(), array $encoders = array()) { foreach ($normalizers as $normalizer) { @@ -203,35 +205,37 @@ public function supportsDenormalization($data, $type, $format = null, array $con * * @return NormalizerInterface|null */ - private function getNormalizer($data, $format, array $context) + private function getNormalizer($data, ?string $format, array $context) { - $type = \is_object($data) ? 'c-'.\get_class($data) : \gettype($data); - if ( - isset($this->normalizerCache[$type][$format]) || - (isset($this->normalizerCache[$type]) && \array_key_exists($format, $this->normalizerCache[$type])) - ) { - return $this->normalizerCache[$type][$format]; + if ($this->cachedNormalizers !== $this->normalizers) { + $this->cachedNormalizers = $this->normalizers; + $this->denormalizerCache = $this->normalizerCache = array(); } + $type = \is_object($data) ? \get_class($data) : 'native-'.\gettype($data); - $cacheable = true; - foreach ($this->normalizers as $normalizer) { - if (!$normalizer instanceof NormalizerInterface) { - continue; - } + if (!isset($this->normalizerCache[$format][$type])) { + $this->normalizerCache[$format][$type] = array(); - $cacheable = $cacheable && $normalizer instanceof NormalizerWithCacheableSupportResultInterface; - if ($normalizer->supportsNormalization($data, $format, $context)) { - if ($cacheable) { - $this->normalizerCache[$type][$format] = $normalizer; + foreach ($this->normalizers as $k => $normalizer) { + if (!$normalizer instanceof NormalizerInterface) { + continue; } - return $normalizer; + if (!$normalizer instanceof CacheableSupportsMethodInterface) { + $this->normalizerCache[$format][$type][$k] = false; + } elseif ($normalizer->supportsNormalization($data, $format)) { + $this->normalizerCache[$format][$type][$k] = true; + + return $normalizer; + } } } - if ($cacheable) { - // allow to cache primitive types - $this->normalizerCache[$type][$format] = null; + foreach ($this->normalizerCache[$format][$type] as $k => $cached) { + $normalizer = $this->normalizers[$k]; + if ($cached || $normalizer->supportsNormalization($data, $format, $context)) { + return $normalizer; + } } } @@ -245,10 +249,33 @@ private function getNormalizer($data, $format, array $context) * * @return DenormalizerInterface|null */ - private function getDenormalizer($data, $class, $format, array $context) + private function getDenormalizer($data, string $class, ?string $format, array $context) { - foreach ($this->normalizers as $normalizer) { - if ($normalizer instanceof DenormalizerInterface && $normalizer->supportsDenormalization($data, $class, $format, $context)) { + if ($this->cachedNormalizers !== $this->normalizers) { + $this->cachedNormalizers = $this->normalizers; + $this->denormalizerCache = $this->normalizerCache = array(); + } + if (!isset($this->denormalizerCache[$format][$class])) { + $this->denormalizerCache[$format][$class] = array(); + + foreach ($this->normalizers as $k => $normalizer) { + if (!$normalizer instanceof DenormalizerInterface) { + continue; + } + + if (!$normalizer instanceof CacheableSupportsMethodInterface) { + $this->denormalizerCache[$format][$class][$k] = false; + } elseif ($normalizer->supportsDenormalization(null, $class, $format)) { + $this->denormalizerCache[$format][$class][$k] = true; + + return $normalizer; + } + } + } + + foreach ($this->denormalizerCache[$format][$class] as $k => $cached) { + $normalizer = $this->normalizers[$k]; + if ($cached || $normalizer->supportsDenormalization($data, $class, $format, $context)) { return $normalizer; } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy