我尝试寻找类似的问题,但无法做到。
我正在寻找正确方向的推动力。我目前正在做的是 收集远程站点的所有href值的列表,现在因为它们中的一些可以 相对路径,我需要一个构建绝对路径的函数。
因为我有域名(通过使用最后一个网址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
答案 0 :(得分:1)
我认为你需要在href路径上使用正则表达式来确保它是一致的。您还可以从parse_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
如果你想要基本网址的第一个目录,那么在解析的网址路径密钥上使用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值与基本网址的关系,您可以在href值的开头搜索../
或/
的出现,然后相应地调整您的绝对网址。这应该可以帮助您弄清楚场景是什么:
<?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上的演示。
答案 1 :(得分:1)
在从@bozdoz推进正确方向后,我最终编写了自己的函数。
该函数有两个参数,第一个是$ resource,它是相对文件路径。 第二个是基本网址(将用于构建绝对网址)。
这是我的项目设计,我不确定它是否适合任何正在寻找的人 对于类似的解决方案。随意使用它,并提供任何效率改进。
更新版本感谢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;
}
}