PHP:如何解决一个相对的url

我需要一个函数给定一个相对的URL和一个基地返回一个绝对的URL。 我search了许多不同的function。

resolve("../abc.png", "http://example.com/path/thing?foo=bar") # returns http://example.com/abc.png 

有没有规范的方法?

在这个网站上,我看到了很好的Python和C#的例子,让我们得到一个PHP解决scheme。

也许这篇文章可以帮助?

http:// nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL

编辑:为了方便,下面的代码复制

 <?php function rel2abs($rel, $base) { /* return if already absolute URL */ if (parse_url($rel, PHP_URL_SCHEME) != '' || substr($rel, 0, 2) == '//') return $rel; /* queries and anchors */ if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel; /* parse base URL and convert to local variables: $scheme, $host, $path */ extract(parse_url($base)); /* remove non-directory element from path */ $path = preg_replace('#/[^/]*$#', '', $path); /* destroy path if relative url points to root */ if ($rel[0] == '/') $path = ''; /* dirty absolute URL */ $abs = "$host$path/$rel"; /* replace '//' or '/./' or '/foo/../' with '/' */ $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {} /* absolute URL is ready! */ return $scheme.'://'.$abs; } ?> 

如果你有pecl-http,你可以使用http://php.net/manual/en/function.http-build-url.php

 <?php $url_parts = parse_url($relative_url); $absolute = http_build_url($source_url, $url_parts, HTTP_URL_JOIN_PATH); 

例如:

 <?php function getAbsoluteURL($source_url, $relative_url) { $url_parts = parse_url($relative_url); return http_build_url($source_url, $url_parts, HTTP_URL_JOIN_PATH); } echo getAbsoluteURL('http://foo.tw/a/b/c', '../pic.jpg') . "\n"; // http://foo.tw/a/pic.jpg echo getAbsoluteURL('http://foo.tw/a/b/c/', '../pic.jpg') . "\n"; // http://foo.tw/a/b/pic.jpg echo getAbsoluteURL('http://foo.tw/a/b/c/', 'http://bar.tw/a.js') . "\n"; // http://bar.tw/a.js echo getAbsoluteURL('http://foo.tw/a/b/c/', '/robots.txt') . "\n"; // http://foo.tw/robots.txt 

其他已链接在pguardiario的评论中的页面链接的工具: http ://publicmind.in/blog/urltoabsolute/,https: //github.com/monkeysuffrage/phpuri 。

我在http://nadeausoftware.com/articles/2008/05/php_tip_how_convert_relative_url_absolute_url发现了其他工具:;

 require_once 'Net/URL2.php'; $base = new Net_URL2('http://example.org/foo.html'); $absolute = (string)$base->resolve('relative.html#bar'); 
 function absoluteUri($Path, $URI) { # Requires PHP4 or better. $URL = parse_url($URI); $Str = "{$URL['scheme']}://"; if (isset($URL['user']) || isset($URL['pass'])) $Str .= "{$URL['user']}:{$URL['pass']}@"; $Str .= $URL['host']; if (isset($URL['port'])) $Str .= ":{$URL['port']}"; $Str .= realpath($URL['path'] . $Path); # This part might have an issue on windows boxes. if (isset($URL['query'])) $Str .= "?{$URL['query']}"; if (isset($URL['fragment'])) $Str .= "#{$URL['fragment']}"; return $Str; } absoluteUri("../abc.png", "http://example.com/path/thing?foo=bar"); # Should return "http://example.com/abc.png?foo=bar" on Linux boxes. 

我注意到上面的upvoted答案使用正则expression式,这在处理URL时可能是危险的。

这个函数将相对URLparsing为$pgurl 给定的当前页面url, 而不使用正则expression式 。 它成功地解决了:

/home.php?exampletypes,

same-dir nextpage.phptypes,

../...../.../parentdirtypes,

完整的http://example.neturl,

和简写//example.neturl

 //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')); 

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

点函数是多余的,但可读,快速,不使用正则expression式,并将解决99%的典型url(如果你想100%确定,扩展开关块,以支持6 +点,虽然我从来没有在URL中看到过很多点)。

希望这可以帮助,