Repository: symfony/symfony
File: src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php (PHP)

Code before:
        // methods
        $class = ($this->objectClassResolver)($object);
        $reflClass = new \ReflectionClass($class);

        foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
            if (
                0 !== $reflMethod->getNumberOfRequiredParameters()
                || $reflMethod->isStatic()
                || $reflMethod->isConstructor()
                || $reflMethod->isDestructor()
            ) {
                continue;
            }

            $name = $reflMethod->name;
            $attributeName = null;

            // ctype_lower check to find out if method looks like accessor but actually is not, e.g. hash, cancel
            if (match ($name[0]) {
                'g' => str_starts_with($name, 'get') && isset($name[$i = 3]),
                'h' => str_starts_with($name, 'has') && isset($name[$i = 3]),
                'c' => str_starts_with($name, 'can') && isset($name[$i = 3]),
                'i' => str_starts_with($name, 'is') && isset($name[$i = 2]),
                default => false,
            } && !ctype_lower($name[$i])) {
                if ($reflClass->hasProperty($name) || $this->hasParentProperty($reflClass, $name)) {
                    $attributeName = $name;
                } else {
                    $attributeName = substr($name, $i);

                    if (!$reflClass->hasProperty($attributeName)) {
                        $attributeName = lcfirst($attributeName);
                    }
                }
            }

            if (null !== $attributeName && $this->isAllowedAttribute($object, $attributeName, $format, $context)) {
                $attributes[$attributeName] = true;
            }
        }

        // properties
        foreach ($reflClass->getProperties() as $reflProperty) {
            if (!$reflProperty->isPublic()) {
                continue;
            }

            if ($reflProperty->isStatic() || !$this->isAllowedAttribute($object, $reflProperty->name, $format, $context)) {
                continue;
            }


Review comment (suggestion):
```suggestion
                if ($this->hasProperty($reflClass, $name)) {
```

Code after:
        // methods
        $class = ($this->objectClassResolver)($object);
        $reflClass = new \ReflectionClass($class);

        foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
            if (
                0 !== $reflMethod->getNumberOfRequiredParameters()
                || $reflMethod->isStatic()
                || $reflMethod->isConstructor()
                || $reflMethod->isDestructor()
            ) {
                continue;
            }

            $name = $reflMethod->name;
            $attributeName = null;

            // ctype_lower check to find out if method looks like accessor but actually is not, e.g. hash, cancel
            if (match ($name[0]) {
                'g' => str_starts_with($name, 'get') && isset($name[$i = 3]),
                'h' => str_starts_with($name, 'has') && isset($name[$i = 3]),
                'c' => str_starts_with($name, 'can') && isset($name[$i = 3]),
                'i' => str_starts_with($name, 'is') && isset($name[$i = 2]),
                default => false,
            } && !ctype_lower($name[$i])) {
                if ($this->hasProperty($reflMethod, $name)) {
                    $attributeName = $name;
                } else {
                    $attributeName = substr($name, $i);

                    if (!$reflClass->hasProperty($attributeName)) {
                        $attributeName = lcfirst($attributeName);
                    }
                }
            }

            if (null !== $attributeName && $this->isAllowedAttribute($object, $attributeName, $format, $context)) {
                $attributes[$attributeName] = true;
            }
        }

        // properties
        foreach ($reflClass->getProperties() as $reflProperty) {
            if (!$reflProperty->isPublic()) {
                continue;
            }

            if ($reflProperty->isStatic() || !$this->isAllowedAttribute($object, $reflProperty->name, $format, $context)) {
                continue;
            }