The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Универсальное правило Modrewrite"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы WEB технологии (Public)
Изначальное сообщение [ Отслеживать ]

"Универсальное правило Modrewrite"  
Сообщение от Brabus email on 20-Мрт-08, 17:00 
Доброго времени суток.
Eсть ссылки типа:
                           index.php?page=art
                           index.php?page=art&subpage=pic
                           index.php?page=art&subpage=pic&sub2page=pic2

преобразовать в человеческий вид не составляет труда:
                           /art.html
                           /art/pic.html
                           /art/pic/pic2.html

Вопрос заключается вот в чем:
заранее не известна вложенность страниц. Как можно понять выше, структура может быть
                           /art->element1
                           /art->el1->el2->el3 ... ->eln

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

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 20-Мрт-08, 17:30 
>    index.php?page=art
>    index.php?page=art&subpage=pic
>    index.php?page=art&subpage=pic&sub2page=pic2
>
>    /art.html
>    /art/pic.html
>    /art/pic/pic2.html

Как вариант можно заменять строки вида "&sub[цифры]page=" на "/".

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 20-Мрт-08, 17:32 
>Как вариант можно заменять строки вида "&sub[цифры]page=" на "/".

Ой, что за глюки! Имелась в виду строка вида "& sub [цифры] page=" без пробелов.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 20-Мрт-08, 18:00 
>>Как вариант можно заменять строки вида "&sub[цифры]page=" на "/".
>

Эм, да, этот вариант можно рассмотреть :)
Но, вопрос закрывать рано.

Вот к примеру, как я предполагаю переписывать урлы:
для первого уровня вложенности:
          RewriteRule ^([a-z0-9]+)/([a-z0-9]+).html$ index.php?page=$1&subpage=$2
тобишь вводим: /art/pic.html
получаем: index.php?page=art&subpage=pic

Т.к. в адресной строке уже будет ЧПУшный урл, полагаю, то нам надо наоборот "/" превращать в "&sub[цифры]page=". В предыдущем RewriteRule четко задана вложенность, т.е. встречается только 1 "/". Как нам этим правилом пройтись ПО ВСЕМУ урлу в поисках "/", заменяя на "&sub[цифры]page=", еще и вместо [цифры] подставляя порядковый номер?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 21-Мрт-08, 08:39 
А, да, конечно, надо же менять наоборот :) С этим сложнее. Предлагаю немного пересмотреть схему и вместо параметров sub[цифры]page использовать массив subpage примерно так:

  index.php?subpage[]=art&subpage[]=pic&subpage[]=pic2

Тогда скрипт PHP получит массив $_GET["subpage"] = array("art", "pic", "pic2"), что на мой взгляд гораздо удобнее как для RewriteRule, так и для дальнейшего разбора.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 21-Мрт-08, 12:10 
>А, да, конечно, надо же менять наоборот :) С этим сложнее. Предлагаю
>немного пересмотреть схему и вместо параметров sub[цифры]page использовать массив subpage примерно
>так:
>
>  index.php?subpage[]=art&subpage[]=pic&subpage[]=pic2
>
>Тогда скрипт PHP получит массив $_GET["subpage"] = array("art", "pic", "pic2"), что на
>мой взгляд гораздо удобнее как для RewriteRule, так и для дальнейшего
>разбора.

Тоже интересная идея :) Но опять таки для строительства такой ссылки, в RewriteRule нужно четко указывать структуру линка, т.е. количество вложенных "разделов". А оно у нас изменчиво, и зависит от того, как встанут звезды :)

Отсюда немного видоизмененный предыдущий вопрос: как нам этим правилом пройтись ПО ВСЕМУ урлу в поисках "/", заменяя на "&sub[]page="?

Вчера под вечер была еще идейка решения проблемы: при добавлении нового раздела просто дописывать в .htaccess соответствующее правило. Но надо бы рассмотреть альтернативные варианты.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 21-Мрт-08, 18:02 
Я тут подумал, а что, собственно, париться? Можно же сделать это по-простому:

RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)$ index.php?path=$1&%{QUERY_STRING}

Тогда при запросе /art/pic/pic2.html?qq=ww&ee=rr будет вызван index.php?path=art/pic/pic2.html&qq=ww&ee=rr. Дальше на PHP простейший анализ:

$subpage = explode('/', substr($_GET['path'], -5))

И всё.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 21-Мрт-08, 22:39 
>RewriteCond %{REQUEST_URI} \.html$
>RewriteRule ^(.*)$ index.php?path=$1&%{QUERY_STRING}
>
>Тогда при запросе /art/pic/pic2.html?qq=ww&ee=rr будет вызван index.php?path=art/pic/pic2.html&qq=ww&ee=rr. Дальше на PHP простейший анализ:
>
>$subpage = explode('/', substr($_GET['path'], -5))

Да, умно :) Принимать всего одну переменную и ее разбирать... Тут отдельная благодарность, скорее всего этот вариант и реализую.

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

А что если нужно в php-скрипте анализировать связку переменных. Т.е., к примеру, нам нужно проверять переменную 'cat', которая должна быть равна 'art' (index.php?cat=art), потом перменную 'act' с значением 'pic' (index.php?act=pic) и т.д.
Т.е. получаемый урл должен быть вида index.php?cat=art&act=pic.
Вводимый урл: /art/pic/
В вышестоящем примере мы просто получим массив со значениями 'art' и 'pic'.
Т.к. заведомо вложенность категорий не известна, мы не можем на абум в скрипте присвоить соответствующим перменным (cat и act) значения из полученного массива (art и pic).
Как быть тут с более менее оптимальным вариантом?

Как я сказал, можно при добавлении новой категории средствами пхп дописывать в .htaccess новое правило, в котором будет строиться конечный урл вида index.php?cat=$1&act=$2 .
Не нравится то, что постоянно прийдется писать новые правила. А если категорий будет много? :) На каждую по правилу - не оптимально.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 22-Мрт-08, 21:08 
>>RewriteCond %{REQUEST_URI} \.html$
>>RewriteRule ^(.*)$ index.php?path=$1&%{QUERY_STRING}
>>
>>Тогда при запросе /art/pic/pic2.html?qq=ww&ee=rr будет вызван index.php?path=art/pic/pic2.html&qq=ww&ee=rr. Дальше на PHP простейший анализ:
>>
>>$subpage = explode('/', substr($_GET['path'], -5))
>

Кой-чего родил. Тут конечно все зависит от конкретный требований, но в принципе можно и обойтись вышеизложенным вариантом.
Получаем из урла список категорий. И в порядке их следования получаем ихние ID в базе данных.
1-й ($cat1_id = ): select id from cat where name = '$subpage[1]' (т.к. корневая категория всегда будет с уникальным именем)
2-й: select id from cat where name = '$subpage[1]' and parent = '$cat1_id' (т.к. уже вторая категория в таблице может повторятся. Тобишь может быть /art/pic/ и /pass/pic).
Ну и дальше до конечной страницы :)
Блин, такое впечатление, что я изобретаю велосипед :)

P.S.
>>$subpage = explode('/', substr($_GET['path'], -5))

Эта фигня не правильна. В $subpage у нас будет только '.html' :) Проверено.
Проще брать все: $subpage = explode('/', $_GET['path'])
, а потом просто удалять '.html': unset($subpage[последний_элемент]);

Собственно. Покритикуй(те) :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 24-Мрт-08, 11:13 
Да, ошибся маленько, нужно так:

$subpage = explode('/', substr($_GET['path'], 0, -5))

Если нужно /art/pic преобразовать в переменные $cat="art" $act="pic", то после этого можно указать

$cat = array_shift($subpage); $act = array_shift($subpage);

или что-то в этом роде в зависимости от логики программы. Оставшиеся элементы будут в массиве $subpage. Или я что-то про твои "категории" не понял - тогда растолкуй, что хочешь получить в итоге, потому что дальше колдовство с БД совсем непонятно.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 24-Мрт-08, 15:44 
>[оверквотинг удален]
>
>Если нужно /art/pic преобразовать в переменные $cat="art" $act="pic", то после этого можно
>указать
>
>$cat = array_shift($subpage); $act = array_shift($subpage);
>
>или что-то в этом роде в зависимости от логики программы. Оставшиеся элементы
>будут в массиве $subpage. Или я что-то про твои "категории" не
>понял - тогда растолкуй, что хочешь получить в итоге, потому что
>дальше колдовство с БД совсем непонятно.

Что касается "катгорий": цель - дать возможность через панель управления создавать неограниченное количество каталогов (тут я понимаю "категория" как "каталог" в урле), подкаталогов, и страниц в них :)
В принципе за основу возьму explode('/', substr($_GET['path'], 0, -5)) , а дальше уже будет видно, как работать в конкретных условиях.
Спасибо за "беседу" и помощь :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 24-Мрт-08, 21:07 
Еще вот столкнулся с проблемкой. Суть такова:
Есть адреса, к примеру:
        /files/cat1/
        /company/about/
Как мы уже тут говорили, реальный передаваемый адрес будет, к примеру: index.php?path=/files/cat1/ . Его разбираем и дальше, тут не интересно.

Что нужно: передавать ссылки типа index.php?name=[название_первого_каталога]&path=...
т.е., к примеру: index.php?name=files&path=/files/cat1/
Это я планировал сделать в .htaccess. Пишу правила:
        RewriteCond %{REQUEST_URI} ^/(files)/?
        RewriteRule ^(.*)$ index.php?name2=%1&path2=$1&%{QUERY_STRING} [L]
        RewriteRule ^(.*)$ index.php?name=content&path=$1&%{QUERY_STRING} [L]
Как должно быть (думаю): в следствии первого RewriteRule, следующего после RewriteCond апдрес получается index.php?name2=files&path... и преобразование урлов заканчивается.
Если RewriteCond не сработал, выполняется последний урл.

Что мы получаем на практике. На первых приведенных примерах адресов:
В случае /company/about/ - все работает как положено. name имеет знчение content и на этом все заканчивается. Имеем что планировали
print_r($_GET):
    [name] => content
    [path] => company/about/
В случае /files/cat1/ - не имеем что надо.
print_r($_GET):
    [name] => content
    [path] => index.php
    [name2] => files
    [path2] => files/cat1/
схавало оба правила, получилось черти что. Более того, если поменять /files/ на что-то другое, нонсенс:
/filesFailed/cat1/
print_r($_GET):
    [name] => content
    [path] => index.php
    [name2] => files
    [path2] => filesFailed/cat1/
В name2 почему-то вопхнулось только первая часть названия каталога. Однако в RewriteCond у нас явно указано "files" и ничего более.

В чем может быть загвоздка? :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 25-Мрт-08, 09:34 
>        RewriteCond %{REQUEST_URI} ^/(files)/?

...
>В name2 почему-то вопхнулось только первая часть названия каталога. Однако в RewriteCond
>у нас явно указано "files" и ничего более.

А "/?" ни о чём не говорит?

Лично у меня нет никакого желания разбираться в хитросплетениях работы mod_rewrite, поэтому я решил эту задачу за 10 минут на PHP, почти ничего к "реврайту" не добавляя. Вот моё решение:

.htaccess
----------------------------------------------------------------
RewriteEngine on
RewriteBase <мой путь>

RewriteCond %{REQUEST_URI} (\.html|/)$
RewriteRule ^(.*)$ index.php?path=$1&%{QUERY_STRING}
----------------------------------------------------------------

index.php
----------------------------------------------------------------
<?php

header("Content-type: text/plain; charset=UTF-8");

echo '_GET = '; print_r($_GET);

$cats = array('files', 'content', 'foo', 'bar');
$defaultCat = 'content';

$path = ltrim($_GET['path'], '/');

if (preg_match('/\.html$/', $path)) {
    $type = 'html';
    $path = substr($path, 0, -5);
} elseif (preg_match('/\/$/', $path)) {
    $type = 'dir';
    $path = substr($path, 0, -1);
} else {
    die("Oops! I don't understand this path: $path");
}

$subpage = explode('/', $path);

if (in_array($subpage[0], $cats)) {
    $cat = array_shift($subpage);
} else {
    $cat = $defaultCat;
}

echo "type = $type\ncat = $cat\nsubpage = "; print_r($subpage);

?>
----------------------------------------------------------------

Ввожу http://<мой домен>/<мой путь>/files/qq/ww.html?foo=bar, получаю:

_GET = Array
(
    [path] => files/qq/ww.html
    [foo] => bar
)
type = html
cat = files
subpage = Array
(
    [0] => qq
    [1] => ww
)

Ввожу http://<мой домен>/<мой путь>/filesFailed/qq/ww/ee/?foo=bar

_GET = Array
(
    [path] => filesFailed/qq/ww/ee/
    [foo] => bar
)
type = dir
cat = content
subpage = Array
(
    [0] => filesFailed
    [1] => qq
    [2] => ww
    [3] => ee
)

В общем - старик Оккам и принцип KISS рулят, как обычно :)

P.S. Люблю иногда такие задачки порешать...

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 25-Мрт-08, 11:54 
>>        RewriteCond %{REQUEST_URI} ^/(files)/?
>
>...
>>В name2 почему-то вопхнулось только первая часть названия каталога. Однако в RewriteCond
>>у нас явно указано "files" и ничего более.
>
>А "/?" ни о чём не говорит?
>

Конечно же говорит. Это позволяет одинаково работать путям с последним слешем и без него:
/files и /files/
Допустим, если

>Лично у меня нет никакого желания разбираться в хитросплетениях работы mod_rewrite, поэтому

Жаль, на самом деле интересная весчь. Искренне хочется врулить, почему же таки мой вариант не работает как надо. В теории вроде бы все ок :)

>я решил эту задачу за 10 минут на PHP, почти ничего
>к "реврайту" не добавляя. Вот моё решение:
>

Если уже решать это на PHP, мне кажется есть более компактное простое решение. Просто из адреса /files/cat1/ или /company/about/ берем название первого "каталога", и смотрим, если не "files", то name=content. А если "files" (и другие интересующие) - значит name=[название].
Однако хочется разрулить именно с модРеврайтом :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Универсальное правило Modrewrite"  
Сообщение от XAnder (ok) on 25-Мрт-08, 15:02 
>>>        RewriteCond %{REQUEST_URI} ^/(files)/?
>>А "/?" ни о чём не говорит?
>
>Конечно же говорит. Это позволяет одинаково работать путям с последним слешем и
>без него:
>/files и /files/

А мне оно говорит, что под этот шаблон попадает и /files и /filesFailed и /files_что_угодно. Вообще здесь ^/(files)/? эквивалентно ^/(files) - угадай почему :)

>Жаль, на самом деле интересная весчь. Искренне хочется врулить, почему же таки
>мой вариант не работает как надо. В теории вроде бы все
>ок :)

Вещь интересная, но времени мало :(

>Если уже решать это на PHP, мне кажется есть более компактное простое
>решение. Просто из адреса /files/cat1/ или /company/about/ берем название первого "каталога",
>и смотрим, если не "files", то name=content. А если "files" (и
>другие интересующие) - значит name=[название].

Так у меня ровно это и есть.

>Однако хочется разрулить именно с модРеврайтом :)

Попробуй. Если получится, буду рад за тебя.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 25-Мрт-08, 12:30 
>
>А "/?" ни о чём не говорит?
>

С этим разобрался. Прийдется явно указывать последний слеш...

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "Универсальное правило Modrewrite"  
Сообщение от Brabus email on 25-Мрт-08, 16:18 
Спасибо :)
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру