Как обычно реализуют многоуровневую виртуальную структуру URL?

Духовность™

Продвинутый новичок
Как обычно реализуют многоуровневую виртуальную структуру URL?

Привет. Меня интересует, как вы или ваши коллеги обычно реализуют виртуальную иерархическую структуру URL-адресов? Я обычно делал так всегда:

/pages/about.html

- тут всё понятно: pages - имя модуля, about - алиас идентификатора статьи и выборка:
Код:
SELECT * FROM articles WHERE alias = "about"
Но как реализовать структуру, с такими URL-адресами:

/pages/about/
/pages/company/
/pages/company/it/
/pages/company/it/web/
/pages/company/it/web/css/
/pages/company/it/web/js/

Много раз видел, что в базе хранят алиас тупо в виде строки "/pages/company/it/web/" и принцип выборки тот же:

Код:
SELECT * FROM articles WHERE alias = "/pages/company/it/web/"
но если придется поменять часть URL для всей ветки (например, заменить "company" на "firm"), это же придется ручками все править!

В общем, Я ПОНЯТИЯ НЕ ИМЕЮ, как это грамотно сделать. Посоветуйте, пожалуйста.
 

Raziel[SD]

untitled00
а что мешает держать нормальное дерево + алиасы ? в случае изменения, просто перегенируешь алиасы и все.
 

newARTix

Новичок
Я делаю именно так. Каждому узлу в дереве прописываю алиас (slug) и на его основе составляется полный урл до узла.
И в узле указывается к какому контроллеру он относится.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Я ленивый и храню в виде id-parentid и на этапе обработки адреса /company/about/ выбираю все дерево и клепаю массив из дерева с алиасами, а потом сравниваю с адресом в цикле. Все это можно еще и закешировать, но мне лично пока хватает времени генерации страницы в районе 0,003 сек. =^..^=
 

Adelf

Administrator
Команда форума
да. ты понял что я имею в виду?
Скорее всего он понял :)
Меняем /pages/company/ на /pages/firm/
Несложно найти все записи с таким началом URL и поменять.
 

Splurov

Новичок
Несложно найти все записи с таким началом URL и поменять.
И не забыть в отдельной табличке вести лог переименований, чтобы поисковиков и пользователей по правильному адресу перенаправлять.
 

Духовность™

Продвинутый новичок
Скорее всего он понял
Меняем /pages/company/ на /pages/firm/
Несложно найти все записи с таким началом URL и поменять.
ок

получается существует два способа хранения подобного рода структур:

- типичное реляционное хранение с доступом по полному URL-алиасу:
Код:
SELECT * FROM ... WHERE alias = "/company/about/history"
- хранение в виде дерева.

Насчет дерева я не совсем понимаю, а как имея строку "/company/about/history" добираться до последнего потомка history? Не считывать же все дерево начиная с company? Какие вообще преимущества использовать деревья в этой задаче?


И вообще, какой способ думаете лучше?
 

Semen

Семён
У меня так:
Таблица - id, pid, url, name, type, order, active
выбираю
PHP:
$dirs = explode('/', $_SERVER['REDIRECT_URL']);

	function getDirTypeByDirs($dirs){
	$q1=null;
	$q2=null;
	$c=1;
	$count=count($dirs);
		for ($i=2; $i<=$count; $i++){
			if (!empty($dirs[$i])){
			$q1.=", `".LANG."_dirs` t".($c+1);
			$q2.=" AND (t".($c+1).".pid=t".$c.".id AND t".($c+1).".url='".$dirs[$i]."')";
			$c++;
			}
		}
	$query="SELECT t".($c).".* FROM `".LANG."_dirs` t1".$q1." WHERE (t1.pid=0 AND t1.url='/') ".$q2.";";
	$res=mysql_query($query, $this->link);
	$dir=mysql_fetch_assoc($res);
	if ($dir['type']==false) erro(__FILE__,__METHOD__, 404);
	return $dir;
	}

	function getDirTypeByClassName($type){
	$query="SELECT * FROM `".LANG."_dirs` WHERE `type`=".quote_smart($type)." LIMIT 1;";
	$res=mysql_query($query, $this->link);
	$dir=mysql_fetch_assoc($res);
	if ($dir['type']==false) erro(__FILE__,__METHOD__, 404);
	return $dir;
	}
 

Adelf

Administrator
Команда форума
Насчет дерева я не совсем понимаю, а как имея строку "/company/about/history" добираться до последнего потомка history? Не считывать же все дерево начиная с company? Какие вообще преимущества использовать деревья в этой задаче?
Имея дерево, мы вводим дополнительное поле - полный url. Его мы пересчитываем каждый раз когда изменяем структуру. По нему и ищем.
Преимущества дерева.. ну мы деревянную структуру представляем именно как деревянную. Мы можем с ней производить все стандартные операции, не изобретая велосипеда. Единственное, что добавляется - пересчет поля url при каждом чихе.
 

pilot911

Новичок
Автор оригинала: triumvirat
ок

получается существует два способа хранения подобного рода структур:

- типичное реляционное хранение с доступом по полному URL-алиасу:
Код:
SELECT * FROM ... WHERE alias = "/company/about/history"
- хранение в виде дерева.

Насчет дерева я не совсем понимаю, а как имея строку "/company/about/history" добираться до последнего потомка history? Не считывать же все дерево начиная с company? Какие вообще преимущества использовать деревья в этой задаче?


И вообще, какой способ думаете лучше?
первый вариант лучше
 

pilot911

Новичок
Автор оригинала: Adelf
А аргументы?
аргументы такие

во-первых, можешь быстро найти нужную страницу
во-вторых, можешь по-разному именовать страницы внутри одного корня (совершенно по-разному, не завися от урла корня)
в-третьих, можешь передать урлы в роутер не руками, а извлекая их из БД - посмотри, как сделано у mzz

ведь как обычно делается.. создается файл, в него кладутся шаблоны урлов и привязываются контроллеры

а так все будет делаться автоматом.. и про файл можно забыть :)

он будет формироваться автоматически в виде (переделал роутер из проекта mzz)

PHP:
if(R::get('ROUTER')->addRoute("13", "13", new RouteRequest(
":language/shop/showcase/:shop_category_url", array(
	"controller" 	=> 	'controller',
	"subcontroller" => 	'index',
	"function"	=>	'getContent',
), 
'return array("language"=>"||ru|en|de");',
'return array();'))) {

}
else if(R::get('ROUTER')->addRoute("14", "14", new RouteRequest(
":language/shop/:shop_category_url/goods/:shop_goods_url", array(
	"controller" 	=> 	'controller',
	"subcontroller" => 	'index',
	"function"	=>	'getContent',
), 
'return array("language"=>"||ru|en|de");',
'return array();'))) {

}
else {
    header("Location: ".Func::redirect( $url_404 ));
    exit();
}
после отработки роутера в $_GET появятся ключи со значениями

$_GET['language']='ru';
$_GET['shop_category_url']='auto';
$_GET['shop_goods_url']='bentli';
 

pilot911

Новичок
Автор оригинала: Adelf
pilot911
Все равно не понял чем тебя не устроило хранение в виде дерева


Китайская подделка? :)
сами страницы можно хранить в виде дерева, но урл потомка не должен зависеть от урла родителя :) для гибкости, конечно! )
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Вопрос. Как тогда вы будите обрабатывать динамические url вида

/company/personnel/vacansy/vacancyid123456/

где 1234... может быть вообще до миллиона.

[пример с вакансиями привел просто так, у меня сие реализовано, хотелось бы увидеть еще варианты =)]
 

Adelf

Administrator
Команда форума
ну единственный раз когда я делал такую структуру работало так:
/company/personnel/vacansy/vacancyid123456/
Ищем в таблице urlы
/company/personnel/vacansy/vacancyid123456/
/company/personnel/vacansy/
/company/personnel/
/company/
И самый точный из них выбираем. А дальше уже рулится контроллером, одним из параметров к которому и идет оставшаяся часть урла.
 
Сверху