1

我尝试寻找类似的问题,但无法找到。

我正在寻找正确方向的推动力。我目前正在做的是收集远程站点的所有 href 值的列表,现在由于其中一些可以是相对路径,我需要一个构建绝对路径的函数。

因为我有域名(通过使用最后一个 url cUrl):

$base_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);

现在让我们说 $base_url 值是:http ://www.example.com/home/index.html 我目前正在阅读的 href 值是:/styles/ie.css

我需要将 $base_url 的值转换为http://www.example.com/styles/ie.css 但我需要该函数尽可能动态。看看可能的情况(可能不是全部):

1 = base url
2 = relative path
------------------------------------------------
1 http://www.example.com/
2 java/popups.js

1 + 2 = http://www.example.com/java/popups.js
------------------------------------------------
1 http://www.example.com
2 java/popups.js

1 + / + 2 = http://www.example.com/java/popups.js
------------------------------------------------
1 http://www.example.com/mysite/
2 ../java/popups.js 

1 - / + (2 - ..) = http://www.example.com/java/popups.js
------------------------------------------------

1 http://www.example.com/rsc/css/intlhplib-min.css
2 ../images/sunflower.png

1 - /css/intlhplib-min.css + (2 - ..) = http://www.example.com/rsc/images/sunflower.png     
4

2 回答 2

1

我认为您需要在 href 路径上使用正则表达式以确保它是一致的。您还可以从parse_url ()中获取准确的基本 url :

<?php
$href = '../images/sunflower.png';
$href = preg_replace('~^\.{0,2}\/~', '', $href);
?>

在这里,我们从字符串的开头去除句点和斜杠。然后添加基本网址:

<?php
$url = 'http://www.example.com/home/index.html';
$url = parse_url($url);

$abspath = $url['scheme'] . '://' . $url['host'] . '/' . $href;

echo $abspath;
?>

应该输出你想要的:http://www.example.com/images/sunflower.png

更新

如果您想要来自基本 url 的第一个目录,则在解析后的 url 的路径键上使用 explode :

$first_directory = '';
if (isset($url['path'])) {
    $patharray = explode('/', $url['path']);
    if (count($patharray)>2){
        $first_directory = explode('/', $url['path'])[1] . '/';
    }
}

并将其添加到输出变量:

$abspath = $url['scheme'] . '://' . $url['host'] . '/' . $first_directory . $href;

另一个更新

要查找 href 值与基本 url 的关系,您可以搜索 href 值的出现..//开头,然后相应地调整绝对 url。这应该可以帮助您弄清楚场景是什么:

<?php
$href = '../../images/sunflower.png';
preg_match('~^(\.{0,2}\/)+~', $href, $matches); //preg_match to check if it exists
if (substr_count($matches[0], '../')){ // substr_count to count number of '../'
    echo 'Go up ' . substr_count($matches[0], '../') . ' directories';
}
else if (substr_count($matches[0], '/')){
    echo 'Root directory';
}
else {
    echo 'Current directory';
}
?>

检查IDEONE上的演示。

于 2013-06-15T20:59:03.553 回答
1

在@bozdoz 朝着正确的方向推进之后,我最终编写了自己的函数。

该函数有两个参数,第一个是 $resource,它是相对文件路径。第二个是基本 url(将用于构造绝对 url)。

这是为我的项目目的而设计的,我不确定它是否适合任何正在寻找类似解决方案的人。随意使用它,并提供任何效率改进。

感谢Tim Cooper的更新版本

function rel2abs_v2($resource, $base_url) 
{
$base_url = parse_url($base_url);

if(substr($resource, 0, 4) !== "http" && substr($resource, 0, 5) !== "https") // if no http/https is present, then {$resource} is a relative path.
{
# There is a "../" in the string
if (strpos($resource, "../") !== false)
{
$dir_count = substr_count($resource, "../");

$path_array = explode("/", $base_url["path"]);
$path_count = count($path_array); // 4
$path_index = ($path_count - $dir_count) - 2;

$resource = trim(str_replace("../", "", $resource));

if($path_index > 0) { $fs = "/"; }

if($dir_count > 0)
{
$base_url_path = implode("/", array_slice($path_array, $dir_count, $path_index - $dir_count + 1));
return $base_url['scheme'] . '://' . $base_url['host'] . $fs . $base_url_path ."/". $resource;
}
}

# Latest addition - remove if unexplained behaviour is in place.
if(starts_with($resource, "//"))
{
return trim(str_replace("//", "", $resource));      
}

if (starts_with($resource, "/"))
{
return $base_url["scheme"] . "://" . $base_url["host"] . $resource;
}
else
{
$path_array = explode("/", $base_url["path"]);

end($path_array);
$last_id = key($path_array);

return $base_url["scheme"] . "://" . $base_url["host"] . "/" . $path_array[--$last_id] . "/" . $resource;
}

}
else
{
return $resource;
}
} 
于 2013-06-16T16:14:42.153 回答