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?example
types,
same-dir nextpage.php
types,
../...../.../parentdir
types,
完整的http://example.net
url,
和简写//example.net
url
//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中看到过很多点)。
希望这可以帮助,