使用PHP将相对路径转换为绝对URL
如何使用php将相对路径转换为绝对URL?实际上不是转换路径而不是URL的问题?PHP实际上有一个用于此的函数:。唯一需要注意的是符号链接使用PHP将相对路径转换为绝对URL,php,parsing,relative-path,Php,Parsing,Relative Path,如何使用php将相对路径转换为绝对URL?实际上不是转换路径而不是URL的问题?PHP实际上有一个用于此的函数:。唯一需要注意的是符号链接 function rel2abs($rel, $base) { /* return if already absolute URL */ if (parse_url($rel, PHP_URL_SCHEME) != '') return $rel; /* queries and anchors */ if ($rel[0]=
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '') 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;
}
PHP手册中的示例:
chdir('/var/www/');
echo realpath('./../../etc/passwd') . PHP_EOL;
// Prints: /etc/passwd
echo realpath('/tmp/') . PHP_EOL;
// Prints: /tmp
如果相对目录已存在,则将执行以下操作:
function rel2abs($relPath, $baseDir = './')
{
if ('' == trim($path))
{
return $baseDir;
}
$currentDir = getcwd();
chdir($baseDir);
$path = realpath($path);
chdir($currentDir);
return $path;
}
我使用了以下相同的代码: 但我对它做了一点修改,所以如果基本url包含端口号,它将返回包含端口号的相对url
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '') 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 // with port number if exists */
if (parse_url($base, PHP_URL_PORT) != ''){
$abs = "$host:".parse_url($base, PHP_URL_PORT)."$path/$rel";
}else{
$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;
}
希望这对别人有帮助 我喜欢jordanstephens从链接中提供的代码!我投了赞成票。l0oky启发我确保该函数与端口、用户名和密码URL兼容。我的项目需要它
function rel2abs( $rel, $base )
{
/* return if already absolute URL */
if( parse_url($rel, PHP_URL_SCHEME) != '' )
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 = '';
/* do we have a user in our URL? */
if( isset($user) )
{
$abs.= $user;
/* password too? */
if( isset($pass) )
$abs.= ':'.$pass;
$abs.= '@';
}
$abs.= $host;
/* did somebody sneak in a port? */
if( isset($port) )
$abs.= ':'.$port;
$abs.=$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 );
}
添加了保留当前查询的支持。对?page=1有很大帮助,依此类推
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '')
return ($rel);
/* queries and anchors */
if ($rel[0] == '#' || $rel[0] == '?')
return ($base . $rel);
/* parse base URL and convert to local variables: $scheme, $host, $path, $query, $port, $user, $pass */
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 = '';
/* do we have a user in our URL? */
if (isset($user)) {
$abs .= $user;
/* password too? */
if (isset($pass))
$abs .= ':' . $pass;
$abs .= '@';
}
$abs .= $host;
/* did somebody sneak in a port? */
if (isset($port))
$abs .= ':' . $port;
$abs .= $path . '/' . $rel . (isset($query) ? '?' . $query : '');
/* replace '//' or '/./' or '/foo/../' with '/' */
$re = ['#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'];
for ($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {
}
/* absolute URL is ready! */
return ($scheme . '://' . $abs);
}
此函数将解析相对URL到
$pgurl
中给定的当前页面URL,而不使用regex。它成功地解决了:
/home.php?示例
类型
相同的目录nextpage.php
类型
。/…/…/parentdir
类型
完整<代码>http://example.netURL
和速记//示例.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转换为绝对URL后必须调用nodots()
dots函数有点冗余,但可读性强,速度快,不使用正则表达式,可以解析99%的典型URL(如果你想100%确定,只需扩展开关块以支持6+个点,尽管我从未见过URL中有这么多点)
希望这能有所帮助,我更新了函数,以修复以“/”开头的相对URL,从而提高了执行速度
function getAbsoluteUrl($relativeUrl, $baseUrl){
// if already absolute URL
if (parse_url($relativeUrl, PHP_URL_SCHEME) !== null){
return $relativeUrl;
}
// queries and anchors
if ($relativeUrl[0] === '#' || $relativeUrl[0] === '?'){
return $baseUrl.$relativeUrl;
}
// parse base URL and convert to: $scheme, $host, $path, $query, $port, $user, $pass
extract(parse_url($baseUrl));
// if base URL contains a path remove non-directory elements from $path
if (isset($path) === true){
$path = preg_replace('#/[^/]*$#', '', $path);
}
else {
$path = '';
}
// if realtive URL starts with //
if (substr($relativeUrl, 0, 2) === '//'){
return $scheme.':'.$relativeUrl;
}
// if realtive URL starts with /
if ($relativeUrl[0] === '/'){
$path = null;
}
$abs = null;
// if realtive URL contains a user
if (isset($user) === true){
$abs .= $user;
// if realtive URL contains a password
if (isset($pass) === true){
$abs .= ':'.$pass;
}
$abs .= '@';
}
$abs .= $host;
// if realtive URL contains a port
if (isset($port) === true){
$abs .= ':'.$port;
}
$abs .= $path.'/'.$relativeUrl.(isset($query) === true ? '?'.$query : null);
// replace // or /./ or /foo/../ with /
$re = ['#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'];
for ($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {
}
// return absolute URL
return $scheme.'://'.$abs;
}
函数url\u到绝对值($baseURL,$relativeURL){
$relativeURL_data=parse_url($relativeURL);
if(isset($relativeEURL_数据['scheme'])){
返回$EURL;
}
$baseURL\u data=parse\u url($baseURL);
如果(!isset($baseURL_data['scheme'])){
返回$EURL;
}
$absoluteURL_数据=$baseURL_数据;
if(isset($relativeURL_数据['path'])和&$relativeURL_数据['path'])){
if(substr($relativeURL_data['path'],0,1)=='/')){
$absoluteURL_数据['path']=$relativeURL_数据['path'];
}否则{
$absoluteURL_data['path']=(isset($absoluteURL_data['path'])?preg_replace(''.[^/]*$.''.''.$absoluteURL_data['path']):'/')。$relativeURL_data['path'];
}
if(isset($relativeEURL_data['query'])){
$absoluteURL_数据['query']=$relativeURL_数据['query'];
}else if(isset($absoluteURL_data['query'])){
未设置($absoluteURL_data['query']);
}
}否则{
$absoluteURL_数据['path']=isset($absoluteURL_数据['path'])?$absoluteURL_数据['path']:'/;
if(isset($relativeEURL_data['query'])){
$absoluteURL_数据['query']=$relativeURL_数据['query'];
}else if(isset($absoluteURL_data['query'])){
$absoluteURL_数据['query']=$absoluteURL_数据['query'];
}
}
if(isset($relativeEURL_数据['fragment'])){
$absoluteURL_数据['fragment']=$relativeURL_数据['fragment'];
}else if(isset($absoluteURL_data['fragment'])){
未设置($absoluteURL_data['fragment']);
}
$absoluteURL_path=ltrim($absoluteURL_data['path'],'/');
$absoluteURL_path_parts=array();
对于($i=0,$i2=0;$i
这是@jordansstephens的答案,他不支持绝对url,答案以“//”开头
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '') return $rel;
/* Url begins with // */
if($rel[0] == '/' && $rel[1] == '/'){
return 'https:' . $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;
}
此版本将以与web浏览器相同的方式解析相对URL
function build_url($parts)
{
$url = $parts['scheme'] . '://';
if (! empty($parts['user'])) {
$url .= $parts['user'];
}
if (! empty($parts['pass'])) {
$url .= ':' . $parts['pass'];
}
if (! empty($parts['user'])) {
$url .= '@';
}
$url .= $parts['host'];
if (! empty($parts['port'])) {
$url .= ':' . $parts['port'];
}
if (! empty($parts['path'])) {
$url .= $parts['path'];
}
if (! empty($parts['query'])) {
$url .= '?' . $parts['query'];
}
if (! empty($parts['fragment'])) {
$url .= '#' . $parts['fragment'];
}
return $url;
}
function absurl($url, $base)
{
$base = parse_url($base);
$_url = parse_url($url);
if (! empty($_url['scheme'])) {
// The URL is already absolute
return $url;
}
if (! empty($_url['host'])) {
// The URL is only missing the scheme
return $base["scheme"] . ':' . $url;
}
if (! empty($_url['path'])) {
// Combine path and overwrite base url query and fragment
unset($base["query"]);
unset($base["fragment"]);
if (substr($_url['path'], 0, 1) != '/') {
$array = explode('/', $_url['path']);
if (! empty($base['path'])) {
$_array = explode('/', $base['path']);
# Remove the file and/or empty path name(s)
$_array = array_slice($_array, 1, - 1);
$array = array_merge($_array, $array);
}
$path = array();
foreach ($array as $dir) {
if ($dir == '..') {
array_pop($path);
} elseif ($dir != '.') {
$path[] = $dir;
}
}
$_url['path'] = "/" . implode('/', $path);
}
} elseif (! empty($_url['query'])) {
// Overwrite base url query and fragment
unset($base["fragment"]);
}
// else: Overwrite base url fragment
return build_url(array_merge($base, $_url));
}
$base_url = 'https://example.com/path1/path2/path3/path4/file.ext?field1=value1&field2=value2#fragment';
echo absurl("https://_example.com/_path1/_path2/_file.ext?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n";
echo absurl("//_example.com/_path1/_path2/_file.ext?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n";
echo absurl("//_example.com", $base_url) . "\n";
echo absurl("/_path1/_path2/_file.ext?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n";
echo absurl("_path1/_path2/_file.ext", $base_url) . "\n";
echo absurl("./../../_path1/../_path2/file.ext#_fragment", $base_url) . "\n";
echo absurl("?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n";
echo absurl("#_fragment", $base_url) . "\n";
您可以使用此composer软件包来完成此操作。 编写器需要wa72/url
- 将URL字符串解析为对象
- 添加和修改查询参数
- 设置和修改url的任何部分
- 在PHP fashio中测试URL与查询参数的相等性
function build_url($parts) { $url = $parts['scheme'] . '://'; if (! empty($parts['user'])) { $url .= $parts['user']; } if (! empty($parts['pass'])) { $url .= ':' . $parts['pass']; } if (! empty($parts['user'])) { $url .= '@'; } $url .= $parts['host']; if (! empty($parts['port'])) { $url .= ':' . $parts['port']; } if (! empty($parts['path'])) { $url .= $parts['path']; } if (! empty($parts['query'])) { $url .= '?' . $parts['query']; } if (! empty($parts['fragment'])) { $url .= '#' . $parts['fragment']; } return $url; } function absurl($url, $base) { $base = parse_url($base); $_url = parse_url($url); if (! empty($_url['scheme'])) { // The URL is already absolute return $url; } if (! empty($_url['host'])) { // The URL is only missing the scheme return $base["scheme"] . ':' . $url; } if (! empty($_url['path'])) { // Combine path and overwrite base url query and fragment unset($base["query"]); unset($base["fragment"]); if (substr($_url['path'], 0, 1) != '/') { $array = explode('/', $_url['path']); if (! empty($base['path'])) { $_array = explode('/', $base['path']); # Remove the file and/or empty path name(s) $_array = array_slice($_array, 1, - 1); $array = array_merge($_array, $array); } $path = array(); foreach ($array as $dir) { if ($dir == '..') { array_pop($path); } elseif ($dir != '.') { $path[] = $dir; } } $_url['path'] = "/" . implode('/', $path); } } elseif (! empty($_url['query'])) { // Overwrite base url query and fragment unset($base["fragment"]); } // else: Overwrite base url fragment return build_url(array_merge($base, $_url)); } $base_url = 'https://example.com/path1/path2/path3/path4/file.ext?field1=value1&field2=value2#fragment'; echo absurl("https://_example.com/_path1/_path2/_file.ext?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n"; echo absurl("//_example.com/_path1/_path2/_file.ext?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n"; echo absurl("//_example.com", $base_url) . "\n"; echo absurl("/_path1/_path2/_file.ext?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n"; echo absurl("_path1/_path2/_file.ext", $base_url) . "\n"; echo absurl("./../../_path1/../_path2/file.ext#_fragment", $base_url) . "\n"; echo absurl("?_field1=_value1&_field2=_value2#_fragment", $base_url) . "\n"; echo absurl("#_fragment", $base_url) . "\n";