如何在PHP中修复格式错误的URL?

时间:2013-05-11 04:00:32

标签: php regex apache

使用PHP,如何自动修复看似这样的格式错误的网址:

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

并将其重新排列回正确的顺序?:

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

在你提问之前,格式错误的网址的原因完全不受我的控制,原因是客户端库坚持在原始查询字符串参数之后愚蠢地添加尾部斜杠和更多端点。幸运的是,我通过PHP反向代理脚本传递请求,可以想象我可以解决它。请注意:

  1. 查询字符串可能存在也可能不存在
  2. 有时可以正确放置查询字符串
  3. 查询字符串参数名称和值将不同
  4. 查询字符串参数的数量可能会更改
  5. 查询字符串可能并不总是遵循“/”(db /?param = val或db?param = val)
  6. 格式错误的网址将始终包含“?param(s)= value /”模式
  7. 关于如何用PHP解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:1)

更换或修复客户端库可能更容易/更好,因为它没有做它应该做的事情(或者它是为不同的规格而设计的)。

但是有一个可以帮助你的正则表达式。

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

这与示例中格式错误的字符串匹配,与结果字符串不匹配。请参阅Rubular上的工作演示。

您可以像这样使用它(虽然我不确定这是否是处理它的最佳方式,我宁愿修复输出然后尝试使用损坏的输入):

$matches = array();
$is_malformed = preg_match('/(.*?)(\/)?(\?.*)(\/.*)/', $_SERVER['REQUEST_URI'], $matches);
if($is_malformed) {
    $_SERVER['REQUEST_URI'] = $matches[1] . $matches[4] . $matches[2] . $matches[3];
}

答案 1 :(得分:0)

我在另一个question中更普遍地解决了这个问题,并在@Yogesh Suthar的帮助下提出了这个作为一个有效的解决方案(欢迎改进):

$qs_match = array();
$is_malformed = preg_match('$\?(.*?)\/$s', $_SERVER['REQUEST_URI'], $qs_match);
if($is_malformed) {
    $uri_parts = explode('?',$_SERVER['REQUEST_URI']); //break apart at the first query string param
    //per https://stackoverflow.com/questions/4250794/simple-php-regex-question
    $_SERVER['REQUEST_URI'] = $uri_parts[0].preg_replace('/^[^\/]*\//' , '/', $uri_parts[1]).'?'.$qs_match[1]; //recombined but modified part 2
}