Я попытался найти аналогичный вопрос, но не смог.
Я ищу толчок в правильном направлении. В настоящее время я собираю список всех значений 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
Я думаю, вам нужно будет использовать регулярные выражения на пути href, чтобы убедиться, что он согласован. Вы также можете получить точный базовый url от parse_url ():
<?php $href = '../images/sunflower.png'; $href = preg_replace('~^\.{0,2}\/~', '', $href); ?>
Здесь мы отделяем периоды и косые черты от начала строки. А затем добавьте базовый url:
<?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, тогда используйте explode на ключ пути parsed url:
$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 .
В конце концов я написал свою собственную функцию после толчка в правильном направлении от @bozdoz.
Функция принимает два аргумента, первый – это $ resource, который является относительным пути к файлу. И вторым является базовый url (который будет использоваться для построения абсолютного URL-адреса).
Это был проект для моих целей проекта, я не уверен, что он подойдет любому, кто ищет аналогичное решение. Не стесняйтесь использовать его и обеспечивайте любые улучшения эффективности.
Обновленная версия Спасибо Тиму Куперу
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; } }