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 abac37770e333..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 +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 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/CacheableSupportsMethodInterface.php b/src/Symfony/Component/Serializer/Normalizer/CacheableSupportsMethodInterface.php new file mode 100644 index 0000000000000..f3b50be7cdcd3 --- /dev/null +++ b/src/Symfony/Component/Serializer/Normalizer/CacheableSupportsMethodInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +/** + * 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 CacheableSupportsMethodInterface +{ +} diff --git a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php index 68a4cb9213279..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 +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 6a15d8da90270..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 +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 995bdf1441776..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 +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 7ab102ed7a9ec..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 +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 3dd94e07e029b..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 +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 27ccf8023cba3..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 +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 1a7087042567a..488b269d4fa6d 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\CacheableSupportsMethodInterface; /** * Serializer serializes and deserializes data. @@ -55,10 +56,14 @@ class Serializer implements SerializerInterface, ContextAwareNormalizerInterface protected $decoder; /** - * @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) { @@ -200,10 +205,35 @@ 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) { - foreach ($this->normalizers as $normalizer) { - if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format, $context)) { + if ($this->cachedNormalizers !== $this->normalizers) { + $this->cachedNormalizers = $this->normalizers; + $this->denormalizerCache = $this->normalizerCache = array(); + } + $type = \is_object($data) ? \get_class($data) : 'native-'.\gettype($data); + + if (!isset($this->normalizerCache[$format][$type])) { + $this->normalizerCache[$format][$type] = array(); + + foreach ($this->normalizers as $k => $normalizer) { + if (!$normalizer instanceof NormalizerInterface) { + continue; + } + + if (!$normalizer instanceof CacheableSupportsMethodInterface) { + $this->normalizerCache[$format][$type][$k] = false; + } elseif ($normalizer->supportsNormalization($data, $format)) { + $this->normalizerCache[$format][$type][$k] = true; + + return $normalizer; + } + } + } + + foreach ($this->normalizerCache[$format][$type] as $k => $cached) { + $normalizer = $this->normalizers[$k]; + if ($cached || $normalizer->supportsNormalization($data, $format, $context)) { return $normalizer; } } @@ -219,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