1

Symfony's getQueryString method doesn't return modified query parameters. So how should someone go about getting a modified query parameter string?

Example code:

   $request = \Drupal::request();
   $parameter_bag = $request->query;
   $parameter_bag->remove('destination');

   $query = \Drupal::request()->getQueryString();
   $query_array_modified = $parameter_bag->all();

$query in this instance will return the destination query parameter even though it was removed from the ParameterBag. $query_array_modified in this instance will not return the destination query parameter ... as expected.

PS - Feel free to replace \Drupal::request(); with Symfony's request object in example code below if you are using Symfony.

1
  • 1
    What's the actual question?
    – leymannx
    Commented Feb 6, 2020 at 23:57

1 Answer 1

1

Symfony's Request object has a query property that is of type ParameterBag, this maintains an iterable list of parameters. The ParameterBag however is not directly translatable to a query string. This causes issues when trying to use the getQueryString() method after modifying the ParameterBag parameters.

Solution 1 - Create a new query string:

   $request = \Drupal::request();
   $parameter_bag = $request->query;
   $parameter_bag->remove('destination');

   // This has to be http_build_query() because
   // \Drupal::request()->getQueryString() returns the original query string
   // but here we need the modified query string (without destination).
   $query = http_build_query($parameter_bag->all());

Solution 2 - Update all global variables:

    \Drupal::request()->query->remove('destination');
    \Drupal::request()->overrideGlobals();
    $query = \Drupal::request()->getQueryString();

Reference to overrideGlobals()

The main issue is that getQueryString() returns the global server variable query string which doesn't reflect changes to the parameter bag. So editing the parameters is not as straight forward as it used to be. We either have to build a new query string or override ALL global variables. In my particular use case I thought that overwritting all globals was too wide reaching and it would overwrite any changes that other modules implemented that our specific code has no control over so I went with solution 1 above as it is generally a safer piece of code to implement.

My two options for solving this the right way is that:

1) ParameterBag either needs a method to build a query string

2) The request object needs to be able to return modified query parameters. Probably by deprecating / defaulting the existing function to returning the output of a new function called getQueryStringOriginal() and creating another new function called getQueryStringModified().

9
  • Is this an edit to the question or an answer?
    – leymannx
    Commented Feb 6, 2020 at 23:56
  • I answered my own question, this was a similar question but didn't have the full answer I needed: stackoverflow.com/questions/11807888/…
    – ccjjmartin
    Commented Feb 7, 2020 at 0:01
  • I thought that this answer didn't fit into that questions flow so I asked a new one here.
    – ccjjmartin
    Commented Feb 7, 2020 at 0:01
  • If you know of other solutions to get the modified query parameters feel free to post here, I dug into this for a while and that was all I could find.
    – ccjjmartin
    Commented Feb 7, 2020 at 0:05
  • Solution for what problem? Drupal builds URLs using the URL object, specifying a route and the query parameters in the options array. If the query parameters should be copied from the request they come from the query parameter bag. So by default Drupal operates on the modified query parameters.
    – 4uk4
    Commented Feb 8, 2020 at 12:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.