Опять про "фонарные" ЧПУ

MagnetiZ

Новичок
Похоже.
Отошли от темы.
А ведь фонарные урлы - далеко не тривиальная проблема.
Вот в моем случае пришлось переделать старые урлы на новый лад.
При этом Весь механизм строится так
1. Модуль который формирует адреса
2. модуль который их разбирает

Дело в том что все адреса формируются одним модулем (может хорошо а может и нет) так:
1. Начало работы формирования страницы По ходу формирования страницы в определенных местах модули могут быть взаимоподчиненными
и следовательно каждые внутренние их параметры должны включать в себя и параметры родительских модулей.
Для этого собирается стек параметров по виду пар "имя=значение".
В результате при потребности сформировать адрес вызывает модуль который выдает в виде единого адреса собраный набор пар значений.
в качестве примера подчиненности модулей. простой случай многоязычности сайта . если выбран определенный отличный от значения по умолчанию язык,
то ко всем адресам подставляется еще дописывается пара язык=значение
Получается что при формировании адресов нельзя точно предсказать какие параметры будут переданы в текущий момент.
Поначалу при формировании просто все адреса записывались через / так Имя1/значение/имя2/значение и т.д
И для определения параметров даже mod_rewrite не требовался достаточно было включить MultiViews который сам искал первое совпадение на исполняемый файл
а все что лишнее отдавал как GET параметр который парсился отдельно простым explode.
Но такой подход требовал
1. Явно указать имя хотя бы одного существующего скрипта в пути даже если это индексный файл (http://domain/index/name/val/namee1/val)
По сути больше требований нет но все равно сердце не спокойно при таком подходе. какй то он некрасивый.
Плюсы при этом были в том что потребовались минимальные изменения во всем движке. и избавились от явных GET параметров.
Точно можно было определить какой параметр и с каким значением передается
Минусы:
1. В скрипте надо или не надо указывался исполняемый файл (уж точно никому не полезно видеть в пути /index/....)
2. Неизвестна эффективность работы MultiViews (как он ищет)
3. Исходя из того что парамтеры просто склеиваются / то невозможно сформировать пути типа /рубрика/подрубрика/.../статья/что то еще
а пусть будет в виде /рубрика/название рубрики/подрубрика/название подрубрики/статья/название статьи ....

При реализации красивых адресов при помощи mod_rewrite обычно все затачивается (к примеру для новостей год/месяц/день или как то иначе)

Можно для каждого модуля и его параметров указать свой набор правил mod_rewrite
но тогда каждый запрос будет проходить по всем правилам.

Может кто использовал Multiviews кто видел положительные и отрицательные стороны?
Может есть альтернативное решение для ситуации где адреса формируются с учетом заранее заданных параметров?
 

StUV

Rotaredom
А ведь фонарные урлы - далеко не тривиальная проблема.
имхо, проблема как раз надуманная

всего существует два варианта:
1. урл однозначно описывает все пары: имя_переменной = значение (как напр в зф: .../name/value/...)
2. в бизнес логику приложения заложены правила определения соответствия частей урла служебным переменным скрипта
(логика разделения так же жестко прописана в скриптах - хотя логика может быть как угодно сложной)

количество реализаций каждого варианта зависит от конкретных требований конкретной задачи

-~{}~ 31.01.08 14:34:

зы: как правило используется смешанный подход
user-friendly часть урла, необходимая для понимания пользователем "назначения главной части страницы" определяется методом 2.
остальные "служебные параметры", описывающие дополнительную логику отображения материала - определяются "естественным образом" - т.е. способом 1.
 

MagnetiZ

Новичок
У меня эта проблема возникала потому что как раз встала задача переделать урлы на новый лад (так начальству захотелось).
Что эффективнее:
1. Multiviews + разбор всего оставшегося от строки скриптом?
или
использование mod_rewrite с большим набором правил?
Тем более если модулей в движке много то количество правил возрастает либо для каждой реализации движка придется редактировать .htaccess.
 

StUV

Rotaredom
я исходя из причин производительности выбрал
использование mod_rewrite с большим набором правил
для каждой реализации движка придется редактировать .htaccess
-~{}~ 31.01.08 14:57:

т.е. есть стандартный механизм роутинга, определяющий класс "ресурса", отвечающий за формирование страницы
этот класс "знает", что должен получить - т.е. какие переменные, диапазон значений и т.п... + каким образом реагировать на некорректные запросы

дублирование/избыточность кода регулируется наследованием/использованием и т.п.... - в целом структура роутинга похожа на систему классов зенд-контроллера, с некоторым упрощением в части валидации

-~{}~ 31.01.08 14:58:

+
запросы не удовлетворяющие правилам реврайта уходят на 404
 

MagnetiZ

Новичок
Понял проблему!
Если переформулировать вопрос так.
Задача - сделать из старых урлов новые (цель - оптимизация под SEO). Требуется сделать быстро.
В результате применил multiviews - задача решена но адресная строка некрасивая.

Теперь задача оставить ЧПУ (опять же для того же SEO) но чтобы строка была красивой. по виду
/модуль/подмодуль/подподмодуль..... (думаю н более 2-3-х уровней)
Понятно что придется корректировать многое в движке.

---------------------
2 StUV:
Мод реврайт с необходимым и достаточнм набором правил получается все же эффективнее multiviews + explode?
Я ствил на максимальный уровень логирования мод реврайт и увидел что он пропускает через себя все и даже запросы к картинкам.
Multiviews Не логировал. даже если такая опция есть (боюсь :( )


StUV
Можно получить ссылку на литературу по стандартным механизмам роутинга?
 

StUV

Rotaredom
и увидел что он пропускает через себя все и даже запросы к картинкам
да
все запросы/подзапросы, которые не надо реврайтить - пропускаются элементарными правилами в начале .htaccess

---
по поводу производительности
существуют запросы такого вида, для которых требуется валидация регулярками до роутинга (т.е. простое отсеивание невалидных урлов)
тесты показывают, что mod_rewrite _в_разы_ быстрее, чем preg_*

++
в распределенных системах часть запросов должна перенаправляться на внутренние служебные хосты - лучше это делать функционалом проксирования веб-сервера, чем с помощью пхп (выигрыш в производительности вообще очевиден)

-~{}~ 31.01.08 15:52:

MagnetiZ
Можно получить ссылку на литературу по стандартным механизмам роутинга?
как пример:
http://framework.zend.com/manual/en/zend.controller.html
=)

+
можешь посмотреть как оно реализовано в jsp
 

MagnetiZ

Новичок
В общем понял.
все же мод реврайт.

Как же тогда быть с модулем построения адресов.
Он работает так
Допустив системе есть 3 модуля
Модуль1, модуль2, модуль3.
Модуль1 использует модуль2,
модуль2 использует модуль3
(как обучное вложенные подменю)

Для формирования адресов используется вообещ нешний модуль
допустим модульАдресов
Работают так:(жаль UML диаграмму нарисовать не получится)
Модуль1 начинает работу и где то вызывает модуль2. При этом перед вызовом он объявляет в модульАдресов что все ссылки модуля2 должны содержать допустим следующее "праметр_пмодуля1=знач_параметра_модуля1"
Модуль два при вызове модуля3 поступает также как и модуль1
При этом накапливается стек параметров.
По завершеннии модуля его параметр убирается из стека.
в общем - классический пример...

Вопрос вот в чем:
Модуль2 не обязательно взывает именно модуль1. Его может вызывать кто угодно и предварительно оставить в стек свой параметр.
Вот и получается что МодульАдресов склеивает в общую кучу все - не зная того от кого что пришло.
А мод_реврайт также не знает каким образом был сформирован тот или иной адрес.
Вслучае если передавать пару имя/значение - все понятно.
И тут multiviews справится (разве что приходится указывать имя скрипта)
И мод реврайт тоже можно использовать так же (все что нескриптовое передавать как GET парметры и дальше при помощи explode по / разбирать).
но именно вот эта самая пара имя/значение не нравится.

Может как то имет смысл модифицировать модульАдресов чтобы избавиться от явной пары имя/значение ?
 

StUV

Rotaredom
++
можно еще подумать самостоятельно о сущности понятий request/response, как они связаны, как "одно перетекает в другое" - но со стартовой позиции "там все просто и очевидно" ;)

-~{}~ 31.01.08 15:56:

конкретная страница сайта "знает" какие модули она использует
если урл однозначно определяет что хочет увидеть клиент - можно написать класс, который будет подтягивать нужные модули, инициализировать их входными параметрами и забирать у них те части страницы, за которые эти модули отвечают

если разные модули "знают" друг о друге - в идеале это "не есть гут", но вполне может иметь место через инициализацию общими параметрами + об этой связи должен знать класс инициализатор

-~{}~ 31.01.08 15:58:

мод_реврайт также не знает каким образом был сформирован тот или иной адрес
адрес изначально _должен_ быть сформирован в соответствии с теми правилами, на которых строятся реврайты в хтакцессе
никакой магии нет
 

MagnetiZ

Новичок
Я про магию и не думаю.... реалист.
Но не мод_реврайт командует расположением.
Предполагается что правила будут строиться автоматически модулями при формировании конечного варианта движка.

В том то и дело что уровень сцепления тут минимальный.
Все модули используют модульАдресов для передачи своих параметров и для формирования адресной строки.
И этому модуль просто строит адрес на основе уже заложенного стека парамтеров.
Он вообще ничего не знает про модуля которые его используют.
Поэтому . если явно не указывать перед значением параметра имя параметра - то крайне трудно понять какой параметр с каким значением передался.

А очень хочется уйти от вида имя/значение.
Вот на счет страницы в которой выполняется скрипт - то да.
Думаю сделать так
Основной модуль (допустим Модуль1) будет явно указывать в начале адресной строки - как ее разбирать
а уже все последующие имя вызываемые модули будут добавлять свои параметры как и раньше - но уже разбираться они будут в соответствии со спецификатором указанным основным модулем.


Странно - тогда получается можно создать файл с именем этого спецификатора и опять вернуться к multiviews :).
Целесообразно ли это?
 
Сверху