Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP将相对路径转换为绝对URL_Php_Parsing_Relative Path - Fatal编程技术网

使用PHP将相对路径转换为绝对URL

使用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]=

如何使用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]=='#' || $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";