Repository: symfony/symfony
File: src/Symfony/Component/HttpFoundation/AcceptHeader.php (PHP)

Code before:
            }
            $parameterCountA = \count($this->getMediaParams($a));
            $parameterCountB = \count($this->getMediaParams($b));
            if ($parameterCountA !== $parameterCountB) {
                return $parameterCountB <=> $parameterCountA;
            }

            return $a->getIndex() <=> $b->getIndex();
        });
    }

    /**
     * Builds a canonical string representation of attributes.
     *
     * @param array<string, mixed> $attributes
     */
    private function buildCanonicalParams(array $attributes): string
    {
        $normalizedAttributes = [];
        foreach ($attributes as $name => $value) {
            $lowerName = strtolower($name);
            if ('q' === $lowerName) {
                continue;
            }
            $normalizedAttributes[$lowerName] = $value;
        }
        ksort($normalizedAttributes);
        $parameterParts = [];
        foreach ($normalizedAttributes as $name => $value) {
            if (null === $value) {
                $parameterParts[] = $name;
            } else {
                $quotedValue = \is_string($value) && str_contains($value, ' ') ? '"'.addslashes($value).'"' : $value;
                $parameterParts[] = $name.'='.$quotedValue;
            }
        }

        return implode(';', $parameterParts);
    }

    /**
     * Checks if a given header item (range) matches a queried item (value).
     *
     * @param AcceptHeaderItem $item      The item from the Accept header (e.g., text/*;format=flowed)
     * @param AcceptHeaderItem $queryItem The item being queried (e.g., text/plain;format=flowed;charset=utf-8)
     */
    private function matches(AcceptHeaderItem $item, AcceptHeaderItem $queryItem): bool
    {
        $requestedValue = $queryItem->getValue();
        if (!str_contains($requestedValue, '/')) {
            // Charset/Language: exact or *

Review comment (refactor):
Then we could simplify to: 
```suggestion
        unset($attributes['q]);
```

Code after:

        // Handle universal wildcard ranges
        if ('*' === $rangeValue || '*/*' === $rangeValue) {
            return $this->rangeParametersMatch($rangeItem, $queryItem);
        }

        // Queries for '*' only match wildcard ranges (handled above)
        if ('*' === $queryValue) {
            return false;
        }

        // Ensure media vs. non-media consistency
        $isQueryMedia = str_contains($queryValue, '/');
        $isRangeMedia = str_contains($rangeValue, '/');

        if ($isQueryMedia !== $isRangeMedia) {
            return false;
        }

        // Non-media: exact match only (wildcards handled above)
        if (!$isQueryMedia) {
            return $rangeValue === $queryValue && $this->rangeParametersMatch($rangeItem, $queryItem);
        }

        // Media type: type/subtype with wildcards
        [$queryType, $querySubtype] = explode('/', $queryValue, 2);
        [$rangeType, $rangeSubtype] = explode('/', $rangeValue, 2) + [1 => '*'];

        if ('*' !== $rangeType && $rangeType !== $queryType) {
            return false;
        }

        if ('*' !== $rangeSubtype && $rangeSubtype !== $querySubtype) {
            return false;
        }

        // Parameters must match
        return $this->rangeParametersMatch($rangeItem, $queryItem);
    }

    /**
     * Checks if the parameters of a range item are satisfied by the query item.
     *
     * Parameters are case-insensitive; range params must be a subset of query params.
     */
    private function rangeParametersMatch(AcceptHeaderItem $rangeItem, AcceptHeaderItem $queryItem): bool
    {
        $queryAttributes = $this->getMediaParams($queryItem);
        $rangeAttributes = $this->getMediaParams($rangeItem);

        foreach ($rangeAttributes as $name => $rangeValue) {