Подтвердить что ты не робот

Преобразуйте относительный путь в абсолютный URL с помощью PHP

Как, используя php, преобразовать относительный путь к абсолютному URL?

4b9b3361

Ответ 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 */
    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;
}

Ответ 2

Мне нравится код, который предоставляется по ссылке! Я проголосовал за это. l0oky вдохновил меня на то, чтобы функция была совместима с портом, именем пользователя и паролем. Мне это было нужно для моего проекта.

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 );
}

Ответ 3

Добавлена ​​поддержка для сохранения текущего запроса. Помогает много для? 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);
}

Ответ 4

На самом деле не вопрос о преобразовании пути, а не url? PHP на самом деле имеет функцию для этого: realpath(). Единственное, о чем вы должны знать, это символические ссылки.

Пример из руководства PHP:

chdir('/var/www/');
echo realpath('./../../etc/passwd') . PHP_EOL;
// Prints: /etc/passwd

echo realpath('/tmp/') . PHP_EOL;
// Prints: /tmp

Ответ 5

Я обновил функцию, чтобы исправить относительный 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;

}

Ответ 6

function url_to_absolute($baseURL, $relativeURL) {  
    $relativeURL_data = parse_url($relativeURL);

    if (isset($relativeURL_data['scheme'])) {
        return $relativeURL;
    }

    $baseURL_data = parse_url($baseURL);

    if (!isset($baseURL_data['scheme'])) {
        return $relativeURL;
    }

    $absoluteURL_data = $baseURL_data;

    if (isset($relativeURL_data['path']) && $relativeURL_data['path']) {
        if (substr($relativeURL_data['path'], 0, 1) == '/') {
            $absoluteURL_data['path'] = $relativeURL_data['path'];
        } else {
            $absoluteURL_data['path'] = (isset($absoluteURL_data['path']) ? preg_replace('#[^/]*$#', '', $absoluteURL_data['path']) : '/') . $relativeURL_data['path'];
        }

        if (isset($relativeURL_data['query'])) {
            $absoluteURL_data['query'] = $relativeURL_data['query'];
        } else if (isset($absoluteURL_data['query'])) {
            unset($absoluteURL_data['query']);
        }
    } else {
        $absoluteURL_data['path'] = isset($absoluteURL_data['path']) ? $absoluteURL_data['path'] : '/';

        if (isset($relativeURL_data['query'])) {
            $absoluteURL_data['query'] = $relativeURL_data['query'];
        } else if (isset($absoluteURL_data['query'])) {
            $absoluteURL_data['query'] = $absoluteURL_data['query'];
        }
    }

    if (isset($relativeURL_data['fragment'])) {
        $absoluteURL_data['fragment'] = $relativeURL_data['fragment'];
    } else if (isset($absoluteURL_data['fragment'])) {
        unset($absoluteURL_data['fragment']);
    }

    $absoluteURL_path = ltrim($absoluteURL_data['path'], '/');
    $absoluteURL_path_parts = array();

    for ($i = 0, $i2 = 0; $i < strlen($absoluteURL_path); $i++) {
        if (isset($absoluteURL_path_parts[$i2])) {
            $absoluteURL_path_parts[$i2] .= $absoluteURL_path[$i];
        } else {
            $absoluteURL_path_parts[$i2] = $absoluteURL_path[$i];
        }

        if ($absoluteURL_path[$i] == '/') {
            $i2++;
        }
    }

    reset($absoluteURL_path_parts);

    while (true) {
        if (rtrim(current($absoluteURL_path_parts), '/') == '.') {
            unset($absoluteURL_path_parts[key($absoluteURL_path_parts)]);

            continue;
        } else if (rtrim(current($absoluteURL_path_parts), '/') == '..') {
            if (prev($absoluteURL_path_parts) !== false) {
                unset($absoluteURL_path_parts[key($absoluteURL_path_parts)]);
            } else {
                reset($absoluteURL_path_parts);
            }

            unset($absoluteURL_path_parts[key($absoluteURL_path_parts)]);

            continue;
        }

        if (next($absoluteURL_path_parts) === false) {
            break;
        }
    }

    $absoluteURL_data['path'] = '/' . implode('', $absoluteURL_path_parts);

    $absoluteURL = isset($absoluteURL_data['scheme']) ? $absoluteURL_data['scheme'] . ':' : '';
    $absoluteURL .= (isset($absoluteURL_data['user']) || isset($absoluteURL_data['host'])) ? '//' : '';
    $absoluteURL .= isset($absoluteURL_data['user']) ? $absoluteURL_data['user'] : '';
    $absoluteURL .= isset($absoluteURL_data['pass']) ? ':' . $absoluteURL_data['pass'] : '';
    $absoluteURL .= isset($absoluteURL_data['user']) ? '@' : '';
    $absoluteURL .= isset($absoluteURL_data['host']) ? $absoluteURL_data['host'] : '';
    $absoluteURL .= isset($absoluteURL_data['port']) ? ':' . $absoluteURL_data['port'] : '';
    $absoluteURL .= isset($absoluteURL_data['path']) ? $absoluteURL_data['path'] : '';
    $absoluteURL .= isset($absoluteURL_data['query']) ? '?' . $absoluteURL_data['query'] : '';
    $absoluteURL .= isset($absoluteURL_data['fragment']) ? '#' . $absoluteURL_data['fragment'] : '';

    return $absoluteURL;
}

Ответ 7

Если относительный каталог уже существует, это выполнит задание:

function rel2abs($relPath, $baseDir = './')
{ 
if ('' == trim($path))
{
    return $baseDir;
    }
    $currentDir = getcwd();
    chdir($baseDir);
    $path = realpath($path);
    chdir($currentDir);
    return $path;
}

Ответ 8

Эта функция будет разрешать относительный URL-адрес для заданного текущего URL-адреса страницы в $pgurl без регулярного выражения. Он успешно решает:

/home.php?example,

same-dir nextpage.php типы,

../...../.../parentdir,

полные 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'));

nodots() должен быть вызван после преобразования URL в абсолютный.

Функция точек является излишней, но читается, быстро, не использует регулярные выражения и разрешает 99% типичных URL-адресов (если вы хотите быть на 100% уверенным, просто расширяйте блок переключателей для поддержки 6+ точек, хотя я никогда не видел столько точек в URL-адресе).

Надеюсь, что это поможет,

Ответ 9

Я использовал тот же код из: http://nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL но я немного изменил его. Если базовый url содержит номер PORT, он возвращает относительный 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;
}

Надеюсь, это поможет кому-то!