За последние 24 часа нас посетил 22451 программист и 1147 роботов. Сейчас ищут 655 программистов ...

Реализация произвольных ЧПУ. [Рассуждение, поиск алгоритма]

Тема в разделе "Решения, алгоритмы", создана пользователем Koc, 1 мар 2009.

  1. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Возникла проблема. Хочу сделать произвольные ЧПУ для разных страниц. Чем произвольные от непроизвольных отличаются:
    Код (Text):
    1. ?m=goods&id=1   # может быть преобразован к /goods/1
    2. ?m=goods&id=442 # может быть преобразован к /goods/442
    3.  
    4. как я хочу:
    5. ?m=goods&id=1   # может быть преобразован к чему угодно, хоть к /abc
    6. ?m=goods&id=442 # может быть преобразован к чему угодно, хоть к /notebooks/r20xy01.html
    В этом-то и заключается сложность, что в 1 варианте только mod_rewrite используется, а во втором еще похапэ должен выяснять, какую же страницу я хочу получить. Как же это реализовать?

    1) создаем отдельную таблицу `rewrites` (`id`, `string`). Оба поля - уникальные.
    2) к каждой таблице из которой будет производиться вывод добавляем по полю `url_rewrite`, в котором будет храниться id записи `rewrites`.`id`
    3) ?????
    4) PROFIT!!!

    по идее мы в начале index.php должны выбрать строку запроса из `rewrites` (SELECT * FROM `rewrites` WHERE `rewrites`.`string`=$_SERVER['PHP_SELF']). Но этого же недостаточно. У нас еще есть категории (таблица `categories`), новости и тд, и везде свои rewrites.

    Тогда можно в таблицу `rewrites` добавить еще одно поле - action. В котором будут определены действия/строка запроса. Возможно в виде сериализованного массива. То есть таблица будет содержать:
    [sql]1, 'abc', '{$_GET['m']: goods, $_GET['id']: 1}
    2, 'notebooks/r20xy01.html', '{$_GET['m']: goods, $_GET['id']: 442}
    3, 'computers', '{$_GET['m']: category, $_GET['id']: 5}
    [/sql]
    Тогда в начале index.php мы достанем строку, десеаризуем массив и переопределим некоторые значения $_GET, дальше будем работать как обычно.

    А что вы думаете по этому поводу? Я правильно мыслю? Как это делали вы?
     
  2. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    обожаю масленное масло, белые белила и черные чернила.
     
  3. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    а сисястые сиси?
     
  4. S.t.A.M.

    S.t.A.M. Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    1.041
    Симпатии:
    0
    Делаешь одну табличку в которой три поля:
    id
    real_url
    cool_url

    настраивашь Апач что бы все запросы рбрабатывал index.php
    Перед выводом парсишь вывод и меняешь все URL'ы на красивые, занося все соответствия в базу.
    при обращении к странице читаешь url ищешь его в базе, получаешь реальный и понимаешь что дальше делать!
     
  5. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    440Hz
    че не так?
     
  6. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    можно полюбопытствоват ЗАЧЕМ?
     
  7. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    заказчик требует
     
  8. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    если он попросит тебя башку об стену разбить - тоже будешь биться?
     
  9. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Нет. А что, неужели это такая сложно реализуемая задача?
     
  10. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    да нет. просто я много видел идиотских задач. но такую...
    заказчик твой отжигает, сам не зная зачем это ему нужно.

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

    а если тебе POST придет? как будешь обрабатывать?

    в общем задача из разряда того: "что надо сделать потому, что я хочу".
     
  11. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    такие URL есть во многих cms, взять ту же Modera
     
  12. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    У мну так.

    Есть запрос $_GET['q']. В нём строка запроса через мод_реврайт посланая. Есть массив с УРЛами (массив потому что маленький - обычно один-пять масок "произвольных" УРЛов, т.е. алиасов или ссылок, если угодно). В массиве хранится унформация тиапа 'alias' => 'перенаправление' или '/alist(/+)?/i' => 'перенаправление', т.е. с регекспом.

    Берётся массив УРЛов и проверяется сначала на $_GET['q'] == $item (тут алиас) или тоже, но с регекспом и тогда preg_match(). Если тру (знаешь, кто убил Лору Палмер? Это не тру!), то $_GET['q'] = $item. Элементарненько.

    В скрипте ниже $_GET['q'] фильтруется на каку, вырезается всякое типа лишних слэшей и передаются дальше. Модули на $_ГЕТ['ку'] неагируют и заводятся в разных планах (зависит от извращённости модуля в том самом плане). :)
     
  13. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    /me шлёт на 3 буквы при таких запросах, мол программист тут я и нехер учить меня работать.
     
  14. mihdan

    mihdan Активный пользователь

    С нами с:
    6 май 2006
    Сообщения:
    37
    Симпатии:
    0
    Адрес:
    Одинцово
    Если задачу решать через mod_rewrite, можно просто написать [L,QSA] - и будет вам POST
     
  15. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    реши ка ее в связках nginx+fastcgi и IIS ?
    а я пока покурю...
     
  16. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    QSA вобще-то для того, чтобы query string не терялся. А post данные будут приходить на любой url, хз почему они должны зависеть от реализации ЧПУ =)
     
  17. crazy

    crazy Активный пользователь

    С нами с:
    8 авг 2007
    Сообщения:
    20
    Симпатии:
    0
    возьмите с dle-news и не парьтесь :)
     
  18. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    crazy
    Это уже в самом последнем случае
     
  19. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    не так давно обсуждали как делать "произвольные ЧПУ". Сейчас вопрос тоже про ЧПУ, но уже как сделать его ср-вами .htaccess & php.

    итак, продвинутые пацаны говорят, что для абсолютно любого ЧПУ хватит следующих строчек в .htaccess:
    Код (Text):
    1. #
    2. # mod_rewrite rules for handling nice urls
    3. #
    4.  
    5. RewriteEngine On
    6. RewriteBase /
    7.  
    8. # check if requested url is alias
    9. RewriteCond %{REQUEST_FILENAME}  !-d
    10. RewriteCond %{REQUEST_FILENAME}  !-f
    11. RewriteRule .+              index.php     [L]
    то есть если нет запрошенной директории и файла, то мы запросили index.php

    кроме того, можно сделать ЧПУ даже без mod_rewrite, правда ссылки будут выглядеть не /nice-url а /index.php/nice-url . Как продвинутые пацаны делают такие чудеса?
     
  20. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    $_SERVER['REQUEST_URI']
     
  21. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    тю. Неужели все так просто? А почему тогда некоторые создают rewriteMap, а потом указывают его в httpd.conf? Блин, дадеко не каждый хостер позволит редактировать httpd.conf :lol:
     
  22. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    блин, а я же себе задачку подкинул:
    есть категории и nice urls для них:
    тостеры /toster
    холодильники /refregerator
    телевизоpы /av/tv

    и есть производители:
    samsung
    LG
    sony

    и если нам нужно показать телевизоры только от samsung'а url будет: /av/tv/samsung

    Пока что не совсем ясно как это в базе хранить и как потом распарсивать.
     
  23. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    выбирай пупликации для av/tv, при этом фильтруй по производителю прямо в SQL запросе
    или создай отдельную категорию sumsung
    и вообще сделай категории лучше циферными, например вместо /av/tv/samsung => /19/sumsung
     
  24. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    отдельную категорию нельзя, так как samsung производит не только телевизоры но и n-ое количество всякой аппаратуры. И что, для каждой категории аппаратуры создавать подкатегорию samsung? не, так нельзя.

    циферные - не совсем верно. А может заказчик не хочет цифры? Будь я на его месте, так точно не захотел бы.

    как догадаться, что нужно выбрать именно товары из av/tv, а не из av/tv/samsung, которого не существует?

    возможно делать так: ищем запись для av/tv/samsung - ее нет в базе. Распарсиваем строку и ищем записи для av/tv и samsung. Если записей нет и для av/tv, распарсиваем еще раз и ищем для av, tv, samsung. Минусы: многовато запросов. Возможно кеширование частично спасет. А может и не спасет.

    еще как вариант, можно сделать delimitter, что-то типа символа ";". И ссылки для телевизоров от самсунга будут выглядить как: av/tv;samsung . В начале отпарсиваем то, что после delimitter'а и ищем нужные нам записи.

    Но если я хочу вывести телевизоры, производитель которых или samaung или LG? формировать строку таким образом: av/tv;samsung,lg?
     
  25. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    вообщем не знаю как ты с урлами работаешь, у меня так
    /modul_name/action_name/{а дальше может идти всё что угодно, модуль сам возьмёт если ему надо}
    так вот у меня бы это было так
    category/{id}/samsung
    или же просто {id}/samsung
    цифры всегда хорошо, выборка быстрее, авто инкремент, нет проблем с уникальностью
    и почему ты не хочешь цифры, так это большая загадка, если ЧПУ, так это бред, сколько сижу в нэте, всегда запоминал страницы по title а не по урлу