回复 adrian,
非常感谢你的函数。你的相对协议函数存在一个小问题。你需要在将 url 设为路径时移除 //。以下是新的函数。
function resolve_url($base, $url) {
if (!strlen($base)) return $url;
// 步骤 2
if (!strlen($url)) return $base;
// 步骤 3
if (preg_match('!^[a-z]+:!i', $url)) return $url;
$base = parse_url($base);
if ($url{0} == "#") {
// 步骤 2 (片段)
$base['fragment'] = substr($url, 1);
return unparse_url($base);
}
unset($base['fragment']);
unset($base['query']);
if (substr($url, 0, 2) == "//") {
// 步骤 4
return unparse_url(array(
'scheme'=>$base['scheme'],
'path'=>substr($url,2),
));
} else if ($url{0} == "/") {
// 步骤 5
$base['path'] = $url;
} else {
// 步骤 6
$path = explode('/', $base['path']);
$url_path = explode('/', $url);
// 步骤 6a: 从 base 中移除文件
array_pop($path);
// 步骤 6b, 6c, 6e: 添加 url 并从目录部分移除 "." 和 ".."
// the directory portion
$end = array_pop($url_path);
foreach ($url_path as $segment) {
if ($segment == '.') {
// 跳过
} else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
array_pop($path);
} else {
$path[] = $segment;
}
}
// 步骤 6d, 6f: 从文件部分移除 "." 和 ".."
if ($end == '.') {
$path[] = '';
} else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
$path[sizeof($path)-1] = '';
} else {
$path[] = $end;
}
// 步骤 6h
$base['path'] = join('/', $path);
}
// 步骤 7
return unparse_url($base);
}