diff --git a/Normalizer/ObjectNormalizer.php b/Normalizer/ObjectNormalizer.php index c52e9e83..1b51b729 100644 --- a/Normalizer/ObjectNormalizer.php +++ b/Normalizer/ObjectNormalizer.php @@ -33,6 +33,8 @@ final class ObjectNormalizer extends AbstractObjectNormalizer { private static $reflectionCache = []; + private static $isReadableCache = []; + private static $isWritableCache = []; protected PropertyAccessorInterface $propertyAccessor; protected $propertyInfoExtractor; @@ -170,21 +172,23 @@ protected function isAllowedAttribute($classOrObject, string $attribute, ?string if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) { return false; } + $class = \is_object($classOrObject) ? \get_class($classOrObject) : $classOrObject; if ($context['_read_attributes'] ?? true) { - return $this->propertyInfoExtractor->isReadable($class, $attribute) || $this->hasAttributeAccessorMethod($class, $attribute); - } + if (!isset(self::$isReadableCache[$class.$attribute])) { + self::$isReadableCache[$class.$attribute] = $this->propertyInfoExtractor->isReadable($class, $attribute) || $this->hasAttributeAccessorMethod($class, $attribute); + } - if ($this->propertyInfoExtractor->isWritable($class, $attribute)) { - return true; + return self::$isReadableCache[$class.$attribute]; } - if (($writeInfo = $this->writeInfoExtractor->getWriteInfo($class, $attribute)) && PropertyWriteInfo::TYPE_NONE !== $writeInfo->getType()) { - return true; + if (!isset(self::$isWritableCache[$class.$attribute])) { + self::$isWritableCache[$class.$attribute] = $this->propertyInfoExtractor->isWritable($class, $attribute) + || (($writeInfo = $this->writeInfoExtractor->getWriteInfo($class, $attribute)) && PropertyWriteInfo::TYPE_NONE !== $writeInfo->getType()); } - return false; + return self::$isWritableCache[$class.$attribute]; } private function hasAttributeAccessorMethod(string $class, string $attribute): bool