mod_rewrite, cсложности при пошаговом разборе ссылки /catalog/59/product/5/

Гриша К.

Новичок
mod_rewrite, cсложности при пошаговом разборе ссылки /catalog/59/product/5/

Здравствуйте.

При помощи mod_rewrite преобразовываю следующие ссылки (htpp://localhost/catalog/):
# 1 # /catalog/59/ => /catalog/?catid=59
# 2 # /catalog/59/product/5/ => /catalog/product.php?catid=59&productid=5

Настройки .htaccess делаю следующими
# 1 # RewriteRule ^([^/]*)/(.*)$ /catalog/?catid=$1&x=$2 [L,QSA]
# 2 #RewriteRule ^([^/]*)/([^/]*)/([^/]*)/?(.*)$ /catalog/$2.php/?catid=$1&productid=$3 [L,QSA]

Проблемы:
Строчка # 2 # работает (в конце можно убирать слэш, или после слэша может быть что угодно), если нету строчки # 1 #, иначе срабатывает ссылка # 1 #.
Ссылка # 1 # работает только если в конце есть /, т.е. регулярное выражение ^([^/]*)/?(.*)$ - не срабатывает

Подскажите пожалуйста как правильно объеденить эти два регулярных выражения (1 и 2), чтобы работали ссылки (и необязательно со / на конце):
/catalog/
/catalog/59/
/catalog/59/product/
/catalog/59/product/5/
 

ksnk

прохожий
А зачем объединять? mod_rewrite не PHP - много не напишешь.
Нужно написать 4 разных правила. Только, imho лучше писать как-нибудь так

RewriteBase /catalog/
...
# правило для /catalog/xx/yy/zz #
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ /catalog/$2.php/?catid=$1&productid=$3 [L,QSA]

Очень помогает для отладки таких скриптов поставить на тестовом хосте RewriteLog ... и RewriteLogLevel 9
 

Гриша К.

Новичок
ksnk, спасибо большое за ответ.

Вобщем понял ваш пример, попробовал сделать.
Возникла проблема, при определении правила, для
/catalog/x/ => /catalog/?catid=x
/catalog/x => /catalog/?catid=x
RewriteRule ^([^/]+)/$ /catalog/index.php?catid=$1 [L,QSA]
В таком случае нельзя убирать слэш после значения 'x'.

Вот как написать правило для такого случая?
 

ksnk

прохожий
Хм... проще оказалось написать :) mod_rewrite - это, действительно, не PHP, блин... :(
Код:
   RewriteEngine on
   RewriteBase /catalog/
# правило для /catalog/xx/yy/zz #
   RewriteCond %{DOCUMENT_ROOT}/catalog/$2.php -f
   RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$  $2.php?catid=$1&productid=$3 [L]
# правило для /catalog/xx/yy/ #
   RewriteCond %{DOCUMENT_ROOT}/catalog/$2.php -f
   RewriteRule ^([^/]+)/([^/]+)/?$ $2.php?catid=$1&productid=$3 [L]
# правило для /catalog/xx/ #
   RewriteCond %{DOCUMENT_ROOT}/catalog/$1 !-f
   RewriteRule ^([^/]+)/?$  index.php?catid=$1 [L]
# проверка правильного реврайта #
   RewriteCond %{DOCUMENT_ROOT}/catalog/$1 -f
   RewriteRule ^(.*)/?$  $1 [L,QSA]
# сюда идем когда где-то ошибка!!!!!!!!!!! #
   RewriteRule (.*)  index.php?shit=$1 [L]
 

Гриша К.

Новичок
que_bunt, спасибо за ответ.
Данный вариант не сработает.

ksnk, спасибо большое за приведенный правильный пример, он работает.
Я читал некотрую документацию по mod_rewrite (http://phpclub.ru/faq/wakka.php?wakka=chpu&v=z4x и т.д.),
но так и не смог разобраться с тем, что значит '-f' и '!-f' в приведенном вами коде, немогли бы вы мне это пояснить?

Я также не понял для чего необходима проверка правильности реврайта?
RewriteCond %{DOCUMENT_ROOT}/catalog/$1 -f
RewriteRule ^(.*)/?$ $1 [L,QSA]
 

ksnk

прохожий
Про mod_rewrite лучше читать документацию :) http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html.
-f - проверка на то, что файл %{DOCUMENT_ROOT}/catalog/$1 существует и, соответственно,
!-f - не существует
Основная тонкость при создании htaccess, это то, что он отрабатывается несколько раз, при этом на вход его подается уже отреврайченый урл. Это можно осознать и как-то отладить только просмотрев лог-файл, который включается опцией RewriteLog + RewriteLogLevel

-~{}~ 05.09.06 20:46:

Я также не понял для чего необходима проверка правильности реврайта?
Последние два правила - контроль адреса, вводимого вручную.
Это на случай, если при вводе вручную, кто-то ошибся в названии категории или php файла. Иначе будет выдаваться некрасивая 404 ошибка :) Можно, конечно, выкинуть...
 

Гриша К.

Новичок
ksnk, спасибо большое за разъяснения, вы меня этим очень выручили.
Мне тяжеловато изучать что-то новое в программировании, а учитывая мое слабое знание английского, читать документацию на английском у меня не получается пока что.
Конечно лучше почитать про все возможности mod_rewrite, но пока негде.
Возможно исходя из приведенного вами примера, я смогу сделать все необходимые правила для текущего проекта.
И хорошо, что вы написали про лог-файл, подробности я нашел по указанной мной ссылке в предыдущем сообщении.
 

Гриша К.

Новичок
baev, спасибо за ответ.

Я прошелся по все ссылкам статьи раздела FAQ на http://phpclub.ru/faq/wakka.php?wakka=chpu&v=z4x
и искал в яндексе по запросу: mod_rewrite
Но такую ссылку не видел:
http://www.opennet.ru/docs/RUS/mod_rewrite/index.html - Документация на русском.
Спасибо, за совет.
 
Сверху