以前目录的网址修复功能“../”吃域名

时间:2013-01-08 06:40:14

标签: php regex url-rewriting

我有这个功能已经有一段时间了:

function fixLink($url){
    return preg_replace('@/[^/]+/\.\./@','/',$url);
}

它为转弯创造了奇迹:
 http://domain.com/page/../index.html http://domain.com/index.html进入http://domain.com/../index.html 但最近我不得不使用它:
 http://index.html,结果为http://domain.com/index.html

在这种情况下如何保护域名,以便将修复后的链接输出为:{{1}}?

寻找有关如何解决问题的想法,请不要过分使用代码。

1 个答案:

答案 0 :(得分:3)

function fixLink($url) {
    $parts = parse_url($url);
    if (empty($parts['path']) || empty($parts['scheme'])) {
        return $url;
    }
    $parts['path'] = preg_replace('@[^/]+/\.\./@', '', $parts['path']);
    $parts['path'] = preg_replace('@^/\.\./@', '/', $parts['path']);
    $parts['scheme'] .= '://';
    return implode('', $parts);
}

但是,上述并未解决所有情况。更强大的版本是:

function fixLink($url) {
    $parts = parse_url($url);
    if (empty($parts['scheme']) || empty($parts['path'])) {
        return $url;
    }
    $path = array();
    foreach (explode('/', $parts['path']) as $i => $item) {
        if ($item == '..') {
            if (count($path) > 1) {
                array_pop($path);
            }
        } else {
            $path[] = $item;
        }    
    }
    $parts['scheme'] .= '://';
    $parts['path'] = implode('/', $path);
    return implode('', $parts);
}