PHP实现含相对路径的绝对URL转为无相对路径的标准绝对URL
解决PHP中带相对路径的绝对URL标准化问题
嘿,这个问题我之前也碰到过,不用费劲自己写复杂的路径解析逻辑,我给你一个纯原生PHP的函数,只需要传入目标URL就能返回标准化后的绝对URL:
function normalize_url(string $url): string { // 拆分URL的各个组成部分 $urlParts = parse_url($url); // 如果没有路径部分,直接返回原URL if (!isset($urlParts['path'])) { return $url; } // 拆分路径为各个片段 $pathSegments = explode('/', $urlParts['path']); $normalizedSegments = []; foreach ($pathSegments as $segment) { // 忽略当前目录(.)和空片段(比如开头/或者连续//) if ($segment === '.' || $segment === '') { continue; } // 处理上级目录(..):移除最后一个已添加的片段 if ($segment === '..') { array_pop($normalizedSegments); continue; } // 正常路径片段直接加入 $normalizedSegments[] = $segment; } // 重新组装标准化后的路径 $urlParts['path'] = '/' . implode('/', $normalizedSegments); // 拼接所有URL部分,还原完整的绝对URL $scheme = isset($urlParts['scheme']) ? $urlParts['scheme'] . '://' : ''; $host = $urlParts['host'] ?? ''; $port = isset($urlParts['port']) ? ':' . $urlParts['port'] : ''; $userInfo = ''; if (isset($urlParts['user'])) { $userInfo = $urlParts['user']; if (isset($urlParts['pass'])) { $userInfo .= ':' . $urlParts['pass']; } $userInfo .= '@'; } $query = isset($urlParts['query']) ? '?' . $urlParts['query'] : ''; $fragment = isset($urlParts['fragment']) ? '#' . $urlParts['fragment'] : ''; return $scheme . $userInfo . $host . $port . $urlParts['path'] . $query . $fragment; }
测试示例
// 输入带相对路径的URL $originalUrl = 'http://example.com/folder/folder2/../image/test.jpg'; // 调用函数获取标准化URL $normalizedUrl = normalize_url($originalUrl); // 输出:http://example.com/folder/image/test.jpg echo $normalizedUrl;
这个函数的优势在于:
- 仅需传入目标URL作为唯一参数,不需要额外的基目录或相对目录
- 兼容各种URL结构,包括带端口、用户信息、查询参数和锚点的URL
- 纯原生实现,不需要依赖任何第三方库
你还可以测试这些场景验证效果:
http://example.com/a/./b/../c→http://example.com/a/chttp://example.com//test//../demo→http://example.com/demohttp://user:pass@example.com:8080/folder/../file.php?foo=bar#anchor→http://user:pass@example.com:8080/file.php?foo=bar#anchor
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

