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

newARTix

Новичок
ну ни наю...
я делаю наоборот.
в памяти висит таблица поиска по дереву страниц (реально есть проект где статичных страниц около 500, проблем с производительностью нет), далее есть функция которая анализирует request_uri. Разбивает его по слэшам и слева на право пытается определить айдишник запрошенного узла. Грубо говоря так:

$uriParts = explode('/',$_SERVER['REQUEST_URI']);
$parentId = 0;
for($uriParts AS $part) {
$parentId = searchPageIdBySlug($part,$parentId);
if(empty($parentId)) break;
$pageId = $parentId;
}

таким образом находим узел с адресом
/company/personnel/vacansy/
который является модулем вакансий. И ему передаем оставшиеся части URI. А он уже знает че с ними делать. Если не знает, то кидает исключение 404.
 

Adelf

Administrator
Команда форума
newARTix
Ну делать много запросов, чтобы найти урл... Все-таки находить нужное одним запросом более правильно в данной ситуации.
 

newARTix

Новичок
под "в памяти висит таблица поиска", я имел ввиду обычный индексированный массив. Запрос всего один, который выбирает всё дерево целиком. Либо вообще берет его из файлового кэша.
 

pilot911

Новичок
Автор оригинала: Adelf
Вот тут поподробней. А зачем нам тогда дерево? Смысла в нем тогда просто нет.
чтобы удобно было админить, строить меню и тп

согласись, не очень нагляден случай, когда страницы просто идут списком :)

-~{}~ 09.06.10 22:37:

Автор оригинала: c0dex
Вопрос. Как тогда вы будите обрабатывать динамические url вида

/company/personnel/vacansy/vacancyid123456/

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

[пример с вакансиями привел просто так, у меня сие реализовано, хотелось бы увидеть еще варианты =)]
все же просто, я описал выше+newARTix на этой странице пояснил, но не до конца

делается так

например, есть урл /company/personnel/vacansy/vacancyid123456/

шаблон для него - /company/personnel/vacansy/:vacancy_id/ - этот шаблон хранится в базе данных в таблице "Страницы"

выбираем все шаблоны в массив и потом последовательно сверяем в регулярке текущий урл $_SERVER['REQUEST_URI'] с шаблонами из массива

наш искомый урл в регулярке будет выглядеть примерно так: /company/personnel/vacansy/[\d\w]+/

если шаблон из массива подходит, значит это нужная страница, берем далее название контроллера и прочее и запускаем обработку :)
 

HraKK

Мудак
Команда форума
капец вы странные.... хранить весь урл в поле... хранить дополнительное поле... пересчитывать при изменении... фак мой брайн((( Не ожидал.
 

fixxxer

К.О.
Партнер клуба
HraKK

ыхыхых.

я ко второй странице уже начал думать "мля, куда я попал" :)
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
HraKK
моя не странный)) моя хранит по другому насяльника)))
 

Adelf

Administrator
Команда форума
HraKK
fixxxer
сами чего расскажите насчет этого вопроса?
+1
Научите нас, странных :) или меня, странного(про пересчет поля только я вроде додумался)

На одном таком проекте у меня было примерно так. Поле правда не пересчитывалось. Да и эту всю структуру не я придумал, но для той задачи(ооочень ветвистый сайтик) она вполне подошла. И ничего лучшего не придумывалось, да и не хотелось.
 

Gas

может по одной?
я сижу на symfony routing и в целом доволен
функционал мапинга урла на action/controller конечно делается без проблем, а позволяет стандартный формат rout'ов постоить карту сайта, вывести меню раздела, breadcrumbs, куда-то доп. запихнуть аттрибуты, например, что страница скрыта ?
 

craz

Нестандартное звание
PHP:
$router->addRoute('main8',      new Zend_Controller_Router_Route(':url_param_1/:url_param_2/:url_param_3/:url_param_4/:url_param_5/:url_param_6/:url_param_7', array('module' => 'default', 'controller' => 'index', 'action' => 'index')) );
то самая большая вложенность пока больше не надо было - это роутер зенда у меня так строиться

В актионе зенда стандартная функция
PHP:
 final protected function _getParam($paramName, $default = null)     
{         
$value = $this->getRequest()->getParam($paramName); 
        if ((null == $value) && (null !== $default)) 
{             
$value = $default;         
}          
return $value;     
}
PHP:
$this->view->url_param_8 = $param8;
забираем его в своем контроллере

потом берем в индексе(у меня есть надстройка логики над ним)

PHP:
$alias = $this->url_param_1;
потом забираем как хотим

SELECT * FROM obj_page WHERE alias = {$alias}
в табличке кроме других полей есть id, parent_id, alias
ну или папу можем вычислить короче рекурсией строим... вообще очень удобно мне кажеться

то есть чтобы построить урл <a href="/<?=$this->url_param_1?>/<?=$this->url_param_2?>/<?=$this->url_param_3?>" и больше в этом проекте ты никогда не полезешь это менять...


P.s. очень надеюсь что это или самый умный или самый тупой способ) хочется сегодня чего-нить самого самого))
 

HraKK

Мудак
Команда форума
Оптимизируем только то что надо оптимизировать. Денормализируем только то что надо денормализировать. Простое правило.
 

pilot911

Новичок
Автор оригинала: HraKK
Оптимизируем только то что надо оптимизировать. Денормализируем только то что надо денормализировать. Простое правило.
Храк, напрягаешь со своими многозначительными ничегонезначащими фразами.
 

HraKK

Мудак
Команда форума
pilot911
Напрягаю - не читай, тут даже есть вроде функция - не показывать мои сообщения.
 

Духовность™

Продвинутый новичок
Возвращаясь к теме.

Я решил сделать следующее - совместить советы двух сторон, которые спорили в теме. А именно: для каждой категории мы как и прежде храним свой URL-alias, а также храним ПОЛНЫЙ URL от вершины, который генерируем и записываем в дополнительное поле ИСКЛЮЧИТЕЛЬНО при создании/редактировании данных категории.

Получается таблица:

PHP:
id | alias | url
теперь при запросе

/categories/sotovaja_svjaz/phones/siemens/

Я делаю SQL: [sql]SELECT * FROM categories WHERE url = '/categories/sotovaja_svjaz/phones/siemens/'[/sql]

а когда хочу поменять URL одной из вершин, то делаю перегенерацию URL-адресов всех потомков.

Вот как-то так.
 

Adelf

Administrator
Команда форума
А если урл у тебя будет -
"/categories/sotovaja_svjaz/phones/siemens/42" ?
Или у тебя совсем все страницы хранятся в этой табличке?
 

Духовность™

Продвинутый новичок
А если урл у тебя будет -
"/categories/sotovaja_svjaz/phones/siemens/42" ?
[sql]SELECT * FROM categories, products WHERE
categories.id = products.id_category
AND
categories.url = '/categories/sotovaja_svjaz/phones/siemens/'
AND
products.id = 42[/sql]

как-то так.. НО!

Самое главное - URL вида "/categories/sotovaja_svjaz/phones/siemens/42" уже содержит уникальный ID товара и можно делать выборку конкретно по ID=42. Остальная часть урла - "/categories/sotovaja_svjaz/phones/siemens/" по сути даже и не нужна для того, что бы вывести товар. Единственное, для чего она может понадобиться - хлебные крошки. Ну и чисто ЧПУшная фишка, чисто визуальная.
 

vovanium

Новичок
c0dex
+1
имхо есть несколько преимуществ.
1) позволяет проверять права доступа вышестоящих каталогов
2) при построении дерева можно сразу строить хлебные крошки и менюхи в том числе сложные (например, в случаях когда построение менюхи для страниц 3-4 уровня вложенности, зависит от 1-го уровня вложенности).
3) избавляемся от зависимости указывать в пути название модуля (никаких pages), адрес может быть абсолютно любой и в одной цепочке могут быть разные модули к примеру адреса

company/about/
company/news/

более логичны чем

pages/company/about
news/company/

4) рутеры километровые вообще не нужны

но урл потомка не должен зависеть от урла родителя
Ну и нафиг такое нужно? теряется весь смысл ЧПУ, и если убрать часть url то пападешь фиг знает куда.

-~{}~ 02.07.10 15:16:

triumvirat
URL вида "/categories/sotovaja_svjaz/phones/siemens/42" уже содержит уникальный ID
ага, а если у тебя кроме товаров есть какой нибудь faq, новости или что-то еще где в конце url есть номер?
или например "categories/tv/lcd/42" где 42 это 42 дюймовые телеки нужно будет запрещать юзерам вводить названия каталогов состоящие только из цифр?
 

Духовность™

Продвинутый новичок
vovanium

ага, а если у тебя кроме товаров есть какой нибудь faq, новости или что-то еще где в конце url есть номер?
company/about/
company/news/

более логичны чем

pages/company/about
news/company/
- я с этим не согласен и поэтому у меня имя модуля в структуре URL адреса пишется. Итого будет:

/catalog/sotovaja_svjaz/phones/siemens/

и я априори лишён описанной тобой проблемы.


или например "categories/tv/lcd/42" где 42 это 42 дюймовые телеки нужно будет запрещать юзерам вводить названия каталогов состоящие только из цифр?
просто делаем URL вида

/catalog/sotovaja_svjaz/phones/siemens/42/42.xhtml

и роутер сам поймет, что этот URL, с постфиксом .xhtml - для товара. А ID товара сответственно будет предшествующая постфиксу цифра.

-~{}~ 02.07.10 16:31:

Я ленивый и храню в виде id-parentid и на этапе обработки адреса /company/about/ выбираю все дерево и клепаю массив из дерева с алиасами, а потом сравниваю с адресом в цикле.
Я не понял. Вы предлагаете перед КАЖДЫМ запросом стоить дерево из таблицы путей и поочередно сравнивать каждую ветвь с запрошенным REQUEST_URI?
 
Сверху