将相对 URL 转换为绝对 URL

Posted

技术标签:

【中文标题】将相对 URL 转换为绝对 URL【英文标题】:Converting relative URL to absolute 【发布时间】:2014-12-12 23:18:38 【问题描述】:

假设我有一个链接到另一个文档的文档的 URL(可以是绝对的或相对的),我需要这个链接是绝对的。

我制作了一个简单的函数,为几种常见情况提供此功能:

function absolute_url($url,$parent_url)
  $parent_url=parse_url($parent_url);
  if(strcmp(substr($url,0,7),'http://')==0)
    return $url;
  
  elseif(strcmp(substr($url,0,1),'/')==0)
    return $parent_url['scheme']."://".$parent_url['host'].$url;
  
  else
    $path=$parent_url['path'];
    $path=substr($path,0,strrpos($path,'/'));
    return $parent_url['scheme']."://".$parent_url['host']."$path/".$url;
  


$parent_url='http://example.com/path/to/file/name.php?abc=abc';
echo absolute_url('name2.php',$parent_url)."\n";
// output http://example.com/path/to/file/name2.php
echo absolute_url('/name2.php',$parent_url)."\n";
// output http://example.com/name2.php
echo absolute_url('http://name2.php',$parent_url)."\n";
// output http://name2.php

代码可以正常工作,但可能有更多情况,例如 ../../path/to/file.php 不起作用。

那么有没有标准的类或函数比我的函数做得更好(更通用)?

我尝试用谷歌搜索并检查类似的问题(one 和 two),但它看起来像是与服务器路径相关的解决方案,这不是我想要的。

【问题讨论】:

..\..\path\to\file.php 是文件路径,而不是 url,因此需要单独的函数。 @Steve 所以<a href='..\..\path\to\file.php'>file</a>html 文档中不起作用? 它可能,取决于浏览器,但不能保证。 uri(您在链接中放置的内容)应使用正斜杠。我不想尴尬,我真的以为你在谈论文件路径,例如用于 phps include 等。 @Steve 哦!你说得对!我说的是URI。所以我的意思是../../path/to/file.php 这是***.com/questions/4444475/…的副本 【参考方案1】:

此函数将在$pgurl 没有正则表达式中将相对 URL 解析为 给定当前页面 URL。成功解决:

/home.php?example 类型,

same-dir nextpage.php 类型,

../...../.../parentdir 类型,

完整的http://example.net 网址,

和速记//example.net urls

//Current base URL (you can dynamically retrieve from $_SERVER)
$pgurl = 'http://example.com/scripts/php/absurl.php';

function absurl($url) 
 global $pgurl;
 if(strpos($url,'://')) return $url; //already absolute
 if(substr($url,0,2)=='//') return 'http:'.$url; //shorthand scheme
 if($url[0]=='/') return parse_url($pgurl,PHP_URL_SCHEME).'://'.parse_url($pgurl,PHP_URL_HOST).$url; //just add domain
 if(strpos($pgurl,'/',9)===false) $pgurl .= '/'; //add slash to domain if needed
 return substr($pgurl,0,strrpos($pgurl,'/')+1).$url; //for relative links, gets current directory and appends new filename


function nodots($path)  //Resolve dot dot slashes, no regex!
 $arr1 = explode('/',$path);
 $arr2 = array();
 foreach($arr1 as $seg) 
  switch($seg) 
   case '.':
    break;
   case '..':
    array_pop($arr2);
    break;
   case '...':
    array_pop($arr2); array_pop($arr2);
    break;
   case '....':
    array_pop($arr2); array_pop($arr2); array_pop($arr2);
    break;
   case '.....':
    array_pop($arr2); array_pop($arr2); array_pop($arr2); array_pop($arr2);
    break;
   default:
    $arr2[] = $seg;
  
 
 return implode('/',$arr2);

用法示例:

echo nodots(absurl('../index.html'));

nodots() 必须在 URL 转换为绝对 URL 之后调用。

dots 函数有点多余,但可读、快速、不使用正则表达式,并且可以解析 99% 的典型 url(如果你想 100% 确定,只需扩展 switch 块以支持 6+点,虽然我从未在 URL 中看到过这么多点)。

希望这会有所帮助,

【讨论】:

没有测试,但看起来正是我需要的。【参考方案2】:
$uri = "..";
$path = realpath($uri);
$root = realpath($_SERVER["DOCUMENT_ROOT"]);

if($path)
    $path = str_replace($root, "", $path);
    $path = $_SERVER["SERVER_NAME"] . $path;
    $protocol = "http";
    if(isset($_SERVER["HTTPS"]))
        $protocol .= "s";        
    
    $path = "$protocol://$path";
    $path = str_replace("\\", "/", $path);


var_dump($path);

可能有更好/更快的方法,但我只是把它搞砸了......

【讨论】:

我需要用于远程文件的功能,因为我知道此功能仅适用于本地文件。对吗? 是的...我明白了,对不起:)

以上是关于将相对 URL 转换为绝对 URL的主要内容,如果未能解决你的问题,请参考以下文章

从相对 URL 获取绝对 URL。 (IE6问题)

将所有相对 URL 替换为绝对 URL

将相对 url 路径解析为其绝对路径

IIS7.5 URL 重写:不要将 POST 转换为 GET

引用外部文件时将绝对目录转换为相对路径

使用 Bash 将给定当前目录的绝对路径转换为相对路径