Remove parameters from Symfony 4.4 HttpFoundation\Request and re-generate URL

1.7k views Asked by At

I need to re-generate the URL of my page, removing the additional parameters. For example: when I receive:

/bao1/bao2/?removeMe1=anything&keepMe1=anything&removeMe2=&keepMe2=anything

I want to generate the URL with removeMe query var removed, but with everything else intact. Like this:

/bao1/bao2/?keepMe1=anything&keepMe2=anything

I autowired the request:

public function __construct(RequestStack $httpRequest)
{
   $this->httpRequest = $httpRequest;
}

Then I'm playing around like this:

public function getCleanUrl()
{
   // HttpFoundation\Request 
   $currentHttpRequest = $this->httpRequest->getCurrentRequest();

   // Trying to remove the parameters
   $currentHttpRequest->query->remove("removeMe1");

   return $currentHttpRequest->getUri()
}

The query->remove("removeMe1") works, but when I invoke getUri() I still get the full input url, as if remove() was never invoked. I think I'm probably missing to call some kind of $currentHttpRequest->regenerate()->getUri() but I cannot find anything.

2

There are 2 answers

0
yivi On BEST ANSWER

To get the modified URL after calling mutator methods on a Request object, you need to call overrideGlobals().

If not, Request methods will give you results accordin to the original superglobals ($_GET, $_POST, $_SERVER). By calling Request::overrideGlobals() you tell the object not to.

E.g.:

if ($request->query->has('amp') && Request::METHOD_GET === $request->getMethod()) {
   $request->query->remove('amp');
   $request->overrideGlobals();

   return new RedirectResponse($request->getUri(), Response::HTTP_MOVED_PERMANENTLY));
}

Or maybe, something more adjusted to your use case (untested, but the general idea should hold):

$queryParams = array_keys($request->query->all());
$goodParams = ['foo', 'bar', 'baz'];

$badParams = array_diff($queryParams, $goodParams);

foreach ($badParams as $badParam) {
    $request->query->remove($badParam);
}

$request->overrideGlobals();

// get modified URL
echo $request->getUri();
0
Dr. Gianluigi Zane Zanettini On

I had to make this work, so I devised a non-Symfony solution:

$currentHttpRequest = $this->httpRequest->getCurrentRequest();

$arrParams          = $currentHttpRequest->query->all();
$arrParams          = array_intersect_key($arrParams, array_flip([
    "keepMe1", "keepMe2"
]));

$currentUrlNoQs     = strtok($currentHttpRequest->getUri(), '?');

if( empty($arrParams) ) {

    $canonical          = $currentUrlNoQs;

} else {

    $queryString        = http_build_query($arrParams);
    $canonical          = $currentUrlNoQs . '?' . $queryString;
}

return $canonical;

I'm not too fond of it, but it got the job done.