Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I fix a malformed URL in PHP?

Tags:

regex

php

apache

Using PHP, How can I automatically fix a malformed url that looks like this:

/db/?param1=sas23456sdfd&param2=1368115104&parama3=more/resource
    or...
/db?param1=sas23456sdfd&param2=1368115104&parama3=more/resource

and rearrange it back into the proper order like this?:

/db/resource/?param1=sas23456sdfd&param2=1368115104&parama3=more
    or...
/db/resource?param1=sas23456sdfd&param2=1368115104&parama3=more

Before you ask, the cause for the malformed url is completely out of my control, having been caused by a client library that insists on stupidly adding a trailing slash and more endpoints after the original query string parameters. Fortunately, I shuttle requests through a PHP reverse proxy script, so conceivably I can fix it. Please note:

  1. The query string may or may not be present
  2. The query string may sometimes be properly placed
  3. The query string parameter names and values will be different
  4. The quantity of query string parameters may change
  5. The query string may not always follow a "/" (db/?param=val or db?param=val)
  6. The malformed URL will always have a "?param(s)=value/" pattern

Any ideas on how to fix this mess with PHP?

like image 528
Inator Avatar asked Jan 25 '26 21:01

Inator


1 Answers

It's probably easier / better to replace or fix the client library, because it's not doing what it should (or it was designed for different specs).

But there is a regex which can help you.

/(.*?)(\/)?(\?.*)(\/.*)/

This matches the malformed strings in the examples and does not match the result strings. See a working demo at Rubular.

You can use it like this (though I am not sure if this is the best way to handle it, I would rather fix the output then trying to work with broken inputs):

$matches = array();
$is_malformed = preg_match('/(.*?)(\/)?(\?.*)(\/.*)/', $_SERVER['REQUEST_URI'], $matches);
if($is_malformed) {
    $_SERVER['REQUEST_URI'] = $matches[1] . $matches[4] . $matches[2] . $matches[3];
}
like image 135
Arjan Avatar answered Jan 28 '26 11:01

Arjan