Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2015, 18:00   #1
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
По умолчанию ЧПУ, Роутинг, мысли, идеи

Здравствуйте дорогие форумчане =)

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

Начну с примеров по виду ссылок:
Root
/admin

Tree pages
/company
/company/history


Tree: Catalog ->Product
/cms/
/cms/promo
/cms/shop
/cms/corporate
Немного деталей к ссылкам выше:
/module(pages):company
/module(pages):company / module(index):history
/module(pages):about
/module(catalog):cms
/module(catalog):cms / module(catalog):othercms /filter/preset=initial;producer=asus/
/module(catalog):cms / product:promo
/module(catalog):cms / product:corporate
/module(catalog):cms / product:magazine
/module(gallery):gallery / module(image):image
/module(pages):contacts

Ссылка:
tsite/cms/promo/filter/producer=HP,LG,Apple;price=100-130;
Домен/Каталог товаров/Товар/Передаваемые доп. параметры:{producer=HP,LG,Apple;pri ce=100-130}


О расположении страниц в админ-панели.
Любые информационные страницы, новости, каталоги, галереи и прочие страницы сайта(доступные по URL) выводятся в общем дереве.
(Для наглядного примера, в umi-cms тоже структура деревом)

Соответственно это дерево должно позволять создавать такую структуру, как:
- /Страница
- /Страница/Страница
- /Страница/Каталог/Продукты
- /Каталог/Каталог/Продукты
- /Каталог новостей/к.новостей/новость
- /Галерея/Изображения
- /Галерея/Галерея/Изображения
- /Страница/Галерея/Изображения
и другие.

Примечание для Каталога и Дерева сайта:
Каталог - отображается в Дереве сайта.
Товары - НЕ отображаются в Дереве сайта, так-как это будет громоздко и неудобно.

Мы имеем ссылку:
/cms/promo

Преобразовываем её в массив по образцу:

PHP код:
$uri = array(
    
'0' => array(
        
'controller' => 'catalog',
        
'action' => 'cms'
    
),
    
'1' => array(
        
'controller' => 'product',
        
'action' => 'promo'
    
)
); 
1) Что такое Controller? Это выполняемый модуль.
2) Что такое Action? Это выполняемое действие в модуле(нужная страница).

Имеем в базе таблицу `type` и в ней содержится список контроллеров с некоторыми настройками.

Так-как Дерево страниц (независимо от их типа) у нас общее и хранится оно в таблице `sitetree`

Нам понадобятся `type`.id и `type`.controller, а так-же `sitetree`.url и `sitetree`.type
`type`.id - (int) идентификатор контроллера.
`type`.controller - (varchar) имя контроллера.
`sitetree`.type - (int) идентификатор контроллера к которому привязываем страницу.
`sitetree`.url - (varchar) url-страницы (promo)



К этому я прикрепляю поддержку нескольких сайтов на одном движке.
1) Проверяю домен, существует ли такой в базе, активен ли он и прочие проверки.
2) Далее определяются нужные страницы, но уже с привязкой `sitetree`.domain_id == `domain`.id и т.д.
В скрипте используется переменная $_SERVER['SERVER_NAME']

Все банально и просто.

___________________________________
О передаваемых данных на страницу через URL (фильтры, параметры, настройки и т.д.)
PHP код:
$is_param = array('filter''params'); 
tsite/cms/promo/filter/producer=HP,LG,Apple;price=100-130;
корректно будет использовать эту ссылку если CMS=каталог, PROMO=подкаталог, а не как ранее Promo=товар.

Переменная $is_param - задает образцы, по которым идет определение где начинаются ДАННЫЕ.
Для каталогов это: Filter
Для галереи(может быть) это: Views
Для чего-то там еще: Params
и так далее, по вкусу.

По указанной ссылке для примера, получаем массив:
PHP код:
'filter' = array(
    
'producer' => array( 
        
=> 'HP',
        
=> 'LG',
        
=> 'Apple'
    
),
    
'price' => array(
        
'from' => '100',
        
'to' => '130'
    
)

___________________________________
По идее - все работает, на практике вроде как тоже, вот только модули не написаны и инфы там ноль, по этому проверка работоспособности лишь относительна.
InCun вне форума Ответить с цитированием
Старый 01.03.2015, 18:02   #2
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
По умолчанию А ЧТО ЕСЛИ?

А что если!? №0
/testpage производится поиск в `sitetree` и находит нужную информацию(страницу).
Дальше ищется `sitetree`.type == `type`.id и не находится?
Странице присваивается стандартный модуль обработки Pages(Страница) и она отображается корректно, но с неустановленным контроллером, с помощью в будущем созданного дебаггера будет запись в
PHP код:
Log::Error("Страница /testpage (id:121) не может найти требуемый контроллер('id:11') для обработки страницы."); 
А что если!? №1
Если ссылка /catalog1/catalog2/catalog3/tovar1
то Каталог/Каталог/Каталог/Товар ?

А если catalog2/catalog1/catalog3/tovar1
то Каталог/Каталог/Каталог/Товар ?
В первом случае - соблюдается правильная иерархия каталогов.
Во втором случае - иерархия нарушена.

С помощью `sitetree` я сделал зависимость унаследования.

Если /catalog1 == родитель(sub=0) то TRUE, иначе ERROR
Если /catalog1(id) == /catalog2(sub) то TRUE, иначе ERROR
Если /catalog2(id) == /catalog3(sub) то TRUE, иначе ERROR

А что если!? №2
Если /catalog1/catalog2/tovar1 TRUE
Если /catalog1/catalog3/tovar2 TRUE
Если /catalog1/catalog2/catalog3/tovar2 TRUE

То, /catalog1/catalog3/tovar1 = Вернет ошибку, "Этой страницы или товара не существует по данному адресу." (Хотя можно изобрести поиск товара по всем каталогам и на странице ошибки вывести блок с информацией "Возможно вы искали этот товар, он находится в другом разделе").
То, /catalog1(TRUE)/catalog2(TRUE)/catalog3(ERROR: Каталог не найден.) Каталог? Да, потому что в базе `sitetree` он существует.
То, /catalog1(TRUE)/catalog2(TRUE)/catalog4(ERROR: Страница не существует.) Страница? Да, потому что catalog4 не существует в базе `sitetree`.

А что если!? №3
Если ссылка /catalog1/catalog2/catalog3/tovar1[/B]
А если catalog1/catalog2/tovar1
и если catalog1/catalog4/tovar1
В первом случае - Товар1 принадлежит к catalog3 == TRUE
Во втором случае - Товар1 принадлежит к catalog2 == TRUE
В третьем случае - Товар1 принадлежит к catalog4 == FALSE

catalog3 является дочерним элементом catalog2, конечно товар1 будет доступен в родительских каталогах.
но 1 и 2 случай, это дублирование ссылок!

Дубли страниц(варианты):
1) на всех дублях указывать тэг Canonical Link
2) на дублях страниц делать переадресацию на Canonical Link.

Последний раз редактировалось InCun; 01.03.2015 в 18:05.
InCun вне форума Ответить с цитированием
Старый 01.03.2015, 18:04   #3
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
По умолчанию Если видите упущения в логике, или есть вопросы "а что если", с радостью всех выслушаю

Если видите упущения в логике, или есть вопросы "а что если", с радостью всех выслушаю!

И прошу - "А зачем ты это делаешь, бери фреймворк" - избавьте меня от этих советов =)
InCun вне форума Ответить с цитированием
Старый 01.03.2015, 19:35   #4
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Честно говоря, не совсем понял в чём вопрос топика (хотя написано очень многабукаф).
Цитата:
Сообщение от InCun Посмотреть сообщение
Если ссылка /catalog1/catalog2/catalog3/tovar1
то Каталог/Каталог/Каталог/Товар ?

А если catalog2/catalog1/catalog3/tovar1
то Каталог/Каталог/Каталог/Товар ?

В первом случае - соблюдается правильная иерархия каталогов.
Во втором случае - иерархия нарушена.
Если ссылка не корректна, то обычно идёт выдача ошибки по протоколу и перенаправление на страницу "404".
Страницу "404" можно оформить на свой вкус, а информационные сообщения из серии
Цитата:
Сообщение от InCun Посмотреть сообщение
"Этой страницы или товара не существует по данному адресу."
и т.д., которые конкретизируют причину возникновения ошибки будут очень полезны. Однако выдачу самой ошибки (а не только сообщения о ней) всё равно делайте.
Streletz вне форума Ответить с цитированием
Старый 01.03.2015, 23:54   #5
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
Смущение

Цитата:
Сообщение от Streletz Посмотреть сообщение
Честно говоря, не совсем понял в чём вопрос топика (хотя написано очень многабукаф).
вот
Цитата:
Сообщение от InCun Посмотреть сообщение
Если видите упущения в логике, или есть вопросы "а что если", с радостью всех выслушаю!
Цитата:
Сообщение от Streletz Посмотреть сообщение
Если ссылка не корректна, то обычно идёт выдача ошибки по протоколу и перенаправление на страницу "404". Страницу "404" можно оформить на свой вкус, а информационные сообщения из серии и т.д., которые конкретизируют причину возникновения ошибки будут очень полезны. Однако выдачу самой ошибки (а не только сообщения о ней) всё равно делайте.
Все верно, я стараюсь предусмотреть все ошибки в ссылках, что не так просто в связи с специфичностью каждого модуля. Ведь логика у них может быть очень даже разная.

Мне один друг написал пример, а что если ему нужны будут ссылки по типу www.tsite/id123456
То у меня два варианта: 1) Править Роутер, 2) Использовать стандартную логику по средством ДеревоСайта-Страница(users).

1) Ставим в настройках CMS базовым роутером "Users" и идем по ссылке www.tsite/id123456
Когда 'id'+(0-9) = если формат адреса верен, запускаем UserController, если пользователя такого нет по ID! "Будет ошибка 404, пользователь не найден" Так-как адрес введен корректно по синтаксису, а в иных случаях запускаем другой модуль, IndexController или PagesController и т.д. по необходимости. Но, в этом случае возникает необходимость PrimaryModule и SecondaryModule.
Primary - Базовый установлен как Users, он не обрабатывает Дерево Сайта; Secondary - подстраховочный, который по сути и является тем самым модулем Дерево Сайта и запускается всегда, когда не нужен Primary. В этом и выходит необходимость правки Роутинга.
2) Если подключать по стандартной логике модуль, (то есть не базовым, а по умолчанию - ДеревоСайта) по адресу www.tsite/id123456 не получится, так-как у меня логика предусматривается в ином виде Дерево сайта - которое имеет страницу, а страница имеет тип в каком модуле она исполняется. То есть если я создам страницу "Пользователи" по адресу сайта www.tsite/users, то конечно www.tsite/users/id123456 отработает корректно. Но, благодаря гибкости подключаемых модулей, у меня может быть любая ссылка, как www.tsite/u/id123456 или www.tsite/id/123456[ и и т.д. id123456 или 123456 и т.д., все зависит от того как написать модуль пользователей)) не более.


Хотя, благодаря этому примеру, я подумываю, а не прописать ли в каждом контроллере(модуле) функцию специфичного Роутинга под модуль? Хотя как-то пока плохо представляю в себе это(подмену роутинга модулем).
InCun вне форума Ответить с цитированием
Старый 02.03.2015, 01:12   #6
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Цитата:
Сообщение от InCun Посмотреть сообщение
Когда 'id'+(0-9) = если формат адреса верен, запускаем UserController, если пользователя такого нет по ID! "Будет ошибка 404, пользователь не найден"
Возможно, Вы не совсем правильно поняли.
Одно дело просто написать "Ошибка 404". Другое дело выдать сообщение об этом по HTTP.
Цитата:
Сообщение от InCun Посмотреть сообщение
Но, благодаря гибкости подключаемых модулей, у меня может быть любая ссылка, как www.tsite/u/id123456 или www.tsite/id/123456[ и и т.д. id123456 или 123456 и т.д., все зависит от того как написать модуль пользователей)) не более.
ИМХО, если планируется использовать это всё в виде CMS, лучше сделать настройку структуры ссылок, а не переписывать каждый раз под конкретную задачу.
Streletz вне форума Ответить с цитированием
Старый 02.03.2015, 01:16   #7
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
Радость

Цитата:
Сообщение от Streletz Посмотреть сообщение
Возможно, Вы не совсем правильно поняли.
Одно дело просто написать "Ошибка 404". Другое дело выдать сообщение об этом по HTTP.
в Header отправлять статус страницы, эту область я знаю =) Кстати, впервые с этой штукой столкнулся, когда Opencart выдавал Ошибку, а страница 200 OK =))
В любом случае, спасибо что обратили на это внимание, кто будет читать и думать о своем, ему будет полезно знать это!))

Цитата:
Сообщение от Streletz Посмотреть сообщение
ИМХО, если планируется использовать это всё в виде CMS, лучше сделать настройку структуры ссылок, а не переписывать каждый раз под конкретную задачу.
Да, нужно продумать как это сделать корректнее. Есть идеи\предположения?
InCun вне форума Ответить с цитированием
Старый 02.03.2015, 01:27   #8
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Цитата:
Сообщение от InCun Посмотреть сообщение
Да, нужно продумать как это сделать корректнее. Есть идеи\предположения?
Реализация настройки ссылок есть во многих открытых CMS и фреймворках. Говорю это вовсе не для того чтобы предложить Вам перейти на готовое решение. Просто ознакомление с готовыми вариантами позволяет посмотреть как это может быть сделано. В любом случае, Вам придётся для своей CMS делать свою реализацию. Тем более, что, по содержанию предыдущих постов, она не стандартная.

Последний раз редактировалось Streletz; 02.03.2015 в 01:33.
Streletz вне форума Ответить с цитированием
Старый 02.03.2015, 03:08   #9
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
Счастье

Спасибо =))

____________________________


Мне тут привели пример с другой CMS, но не знаю какой, но перейду сразу к сути.

Если
PHP код:
array('controller'=>'user','action'=>'profile''id'=>15
Как это будет выглядеть у меня?
В Дереве сайта создается страница url=users, ей присваивается контроллер Users.
URL->Все пользователи => tsite/users
URL->Пользователь => tsite/users/15 (profile default)
URL->Пользователь->Сообщения => tsite/users/15/messages
это пример - так-как модули еще не реализованы.
InCun вне форума Ответить с цитированием
Старый 02.03.2015, 06:27   #10
InCun
Пользователь
 
Аватар для InCun
 
Регистрация: 11.04.2009
Сообщений: 64
По умолчанию

Спасибо =))

____________________________


Мне тут привели пример с другой CMS, но не знаю какой, но перейду сразу к сути.

Если
PHP код:
array('controller'=>'user','action'=>'profile''id'=>15
Как это будет выглядеть у меня?
В Дереве сайта создается страница url=users, ей присваивается контроллер Users.
URL->Все пользователи => tsite/users
URL->Пользователь => tsite/users/15 (profile default)
URL->Пользователь->Сообщения => tsite/users/15/messages
это пример - так-как модули еще не реализованы.


________________________

От вопроса о users/profile/15 вытекает другая мысль, а как движок будет понимать, что /messages или /profile это действие отличное от стандартного, в контроллере Users, а не отдельная страница в sitetree.

Тут мысля о том, что нужна какая-то функция.. для продолжения обработки Роутинга самим Контроллером.
С одной стороны - мы получим 100% корректность\уникальность работы ссылок.
С другой стороны - мы усложняем разработку новых модулей и отладку роутинга в целом (где-то что-то изменить в нем, так все модули переписать не дай бог придется).
Помним о формате URI после! разбора ссылки.
PHP код:
$uri = array( 
    
'0' => array( 
        
'controller' => 'catalog'
        
'action' => 'cms' 
    
), 
    
'1' => array( 
        
'controller' => 'product'
        
'action' => 'promo' 
    
)
); 
От подобной ссылки /u/15 мы имеем
PHP код:
$uri = array( 
    
'0' => array( 
        
'controller' => 'users'
        
'action' => 'u' 
    
), 
    
'1' => array( 
        
'controller' => 'error'
// тут ошибка, так-как по умолчанию проверяется Sitetree на дочерний элемент
// а его там не будет.
        
'action' => '15' 
    
)
); 
(вообще action надобно бы переименовать в url, дабы не путать понятие controller/action и url-часть ссылки)

Некоторым модулям придется делать свой метод Route.

• Разбиваем ссылку в массив из двух частей: "u" и "15".
• Перебираем данные в соответствующий контроллерам/действиям для каждого элемента(с проверкой в Sitetree).

В процессе перебора...
• Загружаем UsersController.
• Проверяем на существование функции $Users->route();
IF TRUE: Check Url to exist in Sitetree OFF.
IF FALSE: Check Url to exist in Sitetree ON.

Загружать все контроллеры в ссылке?
- Однозначно нет, тут придется делать доп. проверку.

Запутался в этой каше, нужно поспать, набраться сил и приступить обратно к мыслительному процессу.

.
InCun вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ЧПУ в .htaccess Небесный PHP 7 06.12.2013 16:49
ЧПУ в Apache moshkin_ura PHP 4 03.10.2012 13:57
ЧПУ kuba1981 PHP 11 02.10.2012 16:23
Роутинг на сайте CraZZy RabbIt PHP 1 16.05.2012 02:30
Мысли Elm0 Свободное общение 0 23.06.2007 21:42