Url only outputs the last value of a query parameter

Created on 9 March 2019, almost 6 years ago
Updated 17 April 2024, 8 months ago

Problem/Motivation

Drupal uses PHP's parse_str function to parse querystrings in multiple places. This function incorrectly assumes that a parameter name can occur only once and returns just the last value.

Example with drush php:

>>> print \Drupal\Core\Url::fromUri('https://example.com/page?tag=one&tag=two')->toString();
https://example.com/page?tag=two

This behavior is a PHP-ism and is not a web standard. Other platforms may and do use the format of repeated param name to pass multiple values.

Further reading:

Proposed resolution

Implement a version of parse_str that is backwards compatible, i.e. treats ?tag=one&tag=two the same way as ?tag[0]=one&tag[1]=two.

Remaining tasks

  • Decide if this ticket should be for internal and external URLs, or external URLs only. See #31 and #41.
  • Add a way to control the output of query arguments.

User interface changes

None

API changes

New static method Drupal\Core\Url::parseString($string).

Data model changes

None.

Release notes snippet

Fixed a bug in parsing query strings with repeated param names.

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
RoutingΒ  β†’

Last updated about 20 hours ago

Created by

πŸ‡΅πŸ‡±Poland blazey

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡§πŸ‡ͺBelgium jOpdebeeck

    Re-rolled #40 for 9.4.12

  • πŸ‡§πŸ‡ͺBelgium jOpdebeeck

    Remade the patch from #48

    Re-rolled #40 for 9.4.12

  • πŸ‡§πŸ‡ͺBelgium glenndw

    Re-rolled #49 for 10.2.3

  • πŸ‡¬πŸ‡§United Kingdom AndyF

    It looks like there's an unanswered question of ticket scope: are we only interested in external URLs, or should we also deal with internal? Personally I'd suggest that if we can't simply solve both, then it makes sense to at least support external URLs along the lines of #31 and if we want to handle internal links do that in a separate ticket. The only issue with #31 that I can see is the slight WTF you'd get from adding an entirely separate query param to such an external URL: I don't think you'd expect that to change how the duplicate query parameters are handled. ie...

    // Assuming we're using a solution that only implements #31.
    \Drupal\Core\Url::fromUri('https://example.com/page?tag=one&tag=two')->toString();
    // Returns https://example.com/page?tag=one&tag=two
    \Drupal\Core\Url::fromUri('https://example.com/page?tag=one&tag=two', ['query' => ['foo' => 'bar']])->toString();
    // Returns https://example.com/page?tag=two&foo=bar
    
    

    @carolpettirossi could you give any extra detail on why/how you're using local links with duplicate query parameter names? Thanks!

Production build 0.71.5 2024