Эта тема на forum.dklab.ru


Дмитрий Эсс:
Дмитрий Котеров:
Наконец-то руки дошли просмотреть код. Это как раз самый нежелательный путь - разбор url на части. Слишком громоздско.
У меня получилось так:

$abs_path = "http://php.net/manual/test/again/test2/index.php"; // абсолютный путь к странице
$rel_path = "/../../aaa/bbb/ccc/test.php"; // относительный путь к файлу
$abs_parsed = parse_url($abs_path);
if (preg_match("#^\w+://#s", $rel_path)) {
$path = $rel_path;
} elseif ($rel_path{0} == "/") {
$path = str_replace($abs_parsed["scheme"].":/", $abs_parsed["scheme"]."://", preg_replace("#[\\\\//]+#s", "/", preg_replace("#^(\w+://[^/]+).*$#s", "\\1", $abs_path).$rel_path));
} else {
$path = str_replace($abs_parsed["scheme"].":/", $abs_parsed["scheme"]."://", preg_replace("#[\\\\//]+#s", "/", stristr(realpath(preg_replace("#/[^/]*$#s", "", $abs_path)."/".$rel_path), $abs_parsed["scheme"].":")));
}
echo $path;

Дмитрий Эсс:
Дмитрий Котеров:
Думаешь этот вариант будет работать стабильно?
Дмитрий Эсс:
Напортачил я, сейчас подправлю...
Дмитрий Эсс:
Поправил. Это надо ещё доработать, но принцип ясен.
Орлис: а наоборот? :)
Мне нужно сделать как раз обратное:
из абсолютного адреса (относительного от корня сайта) преобразовать в относительный (относительно данной страницы).

Подскажите, пожалуйста.
Дмитрий Эсс:
Орлис:
Можно поинтересоваться, зачем?
Дмитрий Котеров:
Дмитрий Эсс:
Что-то сложно больно. Я все-таки не понял, что тебе нужно. Самая сложная задача в преобразовании относительного URL в абсолютный - это корректое удаление ".." и "." в пути, чтобы не глючило при любых вариантах.
Дмитрий Эсс:
Дмитрий Котеров:
Наверняка ведь можно обойтись без циклов стандартными функциями.
Как я написал в первом сообщении, заметил, что realpath() обрабатывает ".." и "." корректно и в середине адреса, т.е. на этом можно сыграть (просто прогнать через realpath() 2 склееных адреса). Но возвращается немного поковерканый адрес, например, такой:
d:\home\test\www\http:\php.net\manual\test.php
Вот с регами у меня проблема. Знаю, что можно всё упростить через (?=), но не получается. Можешь попробовать усовершенствовать?
Дмитрий Котеров:
realpath() же может работать только с существующими файлами. Если файла нет, будет ошибка. Разве нет?

К совершенно, используя одни лишь реги удалить .. не получается - по крайней мере, сделать это достаточно универсально. Я много раз пробовал.
Дмитрий Эсс:
realpath() же может работать только с существующими файлами. Если файла нет, будет ошибка. Разве нет?
Хотя в мане и написано:
realpath() returns FALSE on failure, e.g. if the file does not exists.
Код:
echo realpath("gg/gggggg.tt")
работает, хотя такого файла и не существует.
Думаю это относится только к символическим ссылкам.
Дмитрий Эсс:
Дмитрий Котеров:
Страноо. Короче всё ясно, лучше воспользуюсь 100%-ным методом - циклами.
DmitriyPopov:
Текс... Толи я не понял чего надо Дмитрию... Толи... На этом мысль заканчивается...
Несколькими темами ниже лежит мой класс. Как раз над методом, который соединяет абсолютный URL с uri ссылки шел спор между мной и Silent'ом.... И чем она не устраивает? Тем более что класс тот, как раз таки и создан для работы с HTML и URL'ы

<?php
class MyServerLinkSearcher{
/**
* @return string
* @param $base string
* @param $link string
* @desc Сопоставляет базовый адрес и ссылку, и возвращает полную ссылку
*/
function getFullLink($base,$link){



$link_info = parse_url($link);
if (isset($link_info["scheme"])) {
return($link);
}

$base_info = parse_url($base);

if (!isset($base_info['scheme'])){
return false;
}

if (!isset($base_info['path'])){
$base_info['path'] = "/";
}

$base_base = strtolower($base_info["scheme"])."://";

if (isset($base_info["user"])) {
$base_base .= $base_info["user"].":".$base_info["pass"]."@";
}

$base_base .= strtolower($base_info["host"]);
if (isset($base_info["port"])) {
$base_base .= ":".$base_info["port"];
}

$base_path = $base_info["path"];
$base_path = preg_replace("/(.*\/).*/","\\1",$base_path);



if ($link_info["path"] == "/") {
return $base_base.$link;
}

if (preg_match("'^\./'",$link)) {
$link = preg_replace("'^\./'","",$link);
return $base_base.$base_path.$link;
}


while (preg_match("'^\.\./'",$link)) {
$link = preg_replace("'^\.\./'","",$link);
$base_path = preg_replace("/(.*\/).*\//","\\1",$base_path);
}


if (preg_match('#^/.*#',$link)){
$link = preg_replace('#^/(.*)#',"\\1",$link);
}

return $base_base.$base_path.$link;


}
}

Орлис:
>Дмитрий Эсс
Для движка сайта, в котором session_id храниться в виде виртуального каталога
www.company.com/4761688912/catalog/category/product

Таким образом можно создать _статическую_ версию большинства страниц на сайте, без потери сессии.
Дмитрий Котеров:
Дмитрий Попов:
/a/b/c/./../../../../zz/../../../d/e/f ?
DmitriyPopov:
Дмитрий Котеров:
Хм... и кому-то приходит в голову делать такие ссылки?

Сдаюсь! Делать парсинг для таких ссылок я вряд-ли когда-нибудь буду...
Дмитрий Эсс:
Дмитрий Попов:
Я написал для себя упрощённый вариант функции Д.К.
Извени, может этот код и подошёл бы, но в последнее время на форуме столько сообщений, что темы просматриваю поверхностно. Останавливаюсь только на тех, которые считаю для себя интересными. Видимо придётся отказаться от просмотра некоторых форумов.
Дмитрий Котеров:
Хм... и кому-то приходит в голову делать такие ссылки?
Хакеру. Или в программе автоматически сформируется. Если уж делать готовое решение, то оно должно учитывать все.

Делать парсинг для таких ссылок я вряд-ли когда-нибудь буду...
А и не надо. См. первый мой постинг, там приведен класс.
Дмитрий Котеров:
Выделено из темы «Преобразование url в абсолютный.»,
расположенной в форуме Программирование::PHP::Склад готовых решений (28 Апреля 2004, 17:37).
DmitriyPopov:
Дмитрий Котеров:
Какой то он через чур навороченый.... Что нам надо? Нам надо сделать так, что бы можно было обрабатывать точки посередине.... По сути, если мы приведем адрес к такому виду, что точки и палочки окажутся только в начале, то дальше уже можно воспользоваться хоть моей функцией.... Привести к такмоу виду мы можем... по любому....
Ну дык, почему бы не сделать так:

<?php
$path = "/fsdf/fd/./dff/../../dfdf/./fdfsf/dsfdsfsdf";




$path_arr = explode("/",$path);

//var_dump($path_arr);

while ($s = array_search(".",$path_arr)){
unset($path_arr[$s]);
}

while ($s = array_search("..",$path_arr)){
$i=1;

while(!isset($path_arr[$s-$i])){

if ($s-$i<=0) break;
$i++;
}
if ($s-$i>0){
echo $s - $i;
unset($path_arr[$s-$i]);
unset($path_arr[$s]);
}
}
$path = implode("/",$path_arr);
var_dump($path);
?>
Дмитрий Котеров:
Вот та же самая громоздкость в итоге и получается. (-;
Евгений Галашин:
Ветка выделена в отдельную тему «Как преобразовать URL?»,
расположенную в форуме Лень сходить в Поиск (14 Марта 2005, 17:23).

Эта тема на forum.dklab.ru