#regex #apache #.htaccess #mod-rewrite #clean-urls
#регулярное выражение #apache #.htaccess #мод-перезапись #очистить URL-адреса
Вопрос:
У меня есть предыдущий вопрос, на который был дан очень хороший ответ, но требует исправления, и я не смог ответить, поэтому создал новый вопрос.
Мне потребовался mod_rewrite, который сделал следующее:
www.example.com?page=var1amp;cat=var2amp;subcat=var3amp;subsubcat=var4
в это:
www.example.com/var1/var2/var3/var4/
но это также касалось необязательного использования var2, var3 и var4, поэтому, если бы эти переменные были пустыми, это все равно работало бы.
На вопрос был дан очень хороший ответ, но требуется поправка для работы с различными параметрами полей для var2, var3 и var4.
Код, который у меня есть, это:
RewriteEngine on
Options FollowSymlinks -MultiViews
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/] )/?$ /?page=$1 [L]
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/] )/([^/]*)/?$ /?page=$1amp;cat=$2 [L]
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/] )/([^/]*)/([^/]*)/?$ /?page=$1amp;cat=$2amp;subcat=$3 [L]
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/] )/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1amp;cat=$2amp;subcat=$3amp;subsubcat=$4 [L]
Это работает, но мне нужно, чтобы иметь возможность указать, если или иначе, для выбора того, какое поле используется для какой переменной, и указать разницу.
Например, если у нас обычно есть следующие две строки, легко отличить, какое поле относится к какой переменной:
www.example.com?page=var1amp;cat=var2amp;subcat=var3amp;subsubcat=var4
www.example.com?othervar1=var1amp;othervar2=var2amp;othervar3=var3amp;othervar4=var4
но для этой строки требуется способность различать, для какого поля предназначена переменная:
www.example.com/var1/var2/var3/var4/
Мне нужен mod_rewrite, чтобы выбрать, какой из них используется.
Кроме того, когда я действительно захожу в папку, которая существует, она работает правильно. Например, если я перейду в папку с именем «test», которая является реальной папкой:
www.example.com/test/
он использует его в качестве переменной для поля «страница». Если я использую следующее без косой черты в конце:
www.example.com/test
он выводит следующее в URL:
www.example.com/test/?page=test
Мне нужно, чтобы это работало и для папок, которые существуют в обычном режиме.
Пожалуйста, кто-нибудь может сказать мне, как это можно сделать? Я был бы признателен за любую помощь в решении этой проблемы.
Также, может кто-нибудь сказать мне, что означает бит «-MultiViews» в начале, поскольку я раньше с этим не сталкивался?
Спасибо.
Комментарии:
1. Вам понадобится структура URL, подобная
www.example.com/value1/cat/value2/subcat/value3/subcat/value4/
если вы хотите иметь возможность, например, опускать,cat
но при этом иметь дваsubcat
s. Аналогично с другими переменными. Или я что-то упускаю?
Ответ №1:
ОК, сначала параметры MultiViews: согласно руководству Apache:
MultiViews
Content negotiated "MultiViews" are allowed using mod_negotiation.
Короче говоря, если у вас есть файл с именем foo.html
и если браузер запрашивает http://example.com/foo
, то Apache автоматически находит и добавляет расширение и обслуживает foo.html
браузер, а не выбрасывает 404. Такое поведение приводит к сбою многих правил перезаписи, поэтому я отключил его в начале моего ответа на ваш предыдущий вопрос.
Теперь, чтобы исключить обработку реальных каталогов правилами перезаписи, нам понадобится дополнительное условие, подобное этому: RewriteCond %{REQUEST_FILENAME} !-d
Для поддержки нескольких красивых схем URL:
Здесь у вас есть несколько вариантов. Пожалуйста, скажите мне, какую из них вы хотели бы иметь, и я предоставлю правила для этого.
Вариант 1: Укажите оба var name
и var value
в вашем URL-адресе следующим образом:
www.example.com/page/var1/cat/var2/subcat/var3/subsubcat/var4
или
www.example.com/othervar1/var1/othervar2/var2/othervar3/var3/othervar4/var4
Это дает вам максимальную гибкость и очень легко обрабатывается в правилах перезаписи, если вы готовы пойти по этому маршруту. Для этой опции правила перезаписи нужно будет записать только один раз, и вы будете в порядке для будущих изменений, пока количество переменных не изменится
Вариант 2: Иметь разное начало для каждой схемы. Например:
www.example.com/handler1/var1/var2/var3/var4
или
www.example.com/handler2/var1/var2/var3/var4
Этот дает вам более короткий URL, но не обеспечивает гибкости, как предыдущий вариант. Но с этим также очень легко справиться в правилах перезаписи. Однако для этой опции необходимо будет написать правила перезаписи для каждой комбинации
Итак, я бы рекомендовал вариант 1 и был бы рад подготовить для вас .htaccess, если вам тоже нравится этот вариант.
.файл htaccess для варианта 2
Options FollowSymlinks -MultiViews
RewriteEngine on
# 404 handler
ErrorDocument 404 /notFound.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler1/([^/] )/?$ /?page=$1 [NC,QSA,L]
RewriteRule ^handler1/([^/] )/([^/] )/?$ /?page=$1amp;cat=$2 [NC,QSA,L]
RewriteRule ^handler1/([^/] )/([^/]*)/([^/]*)/?$ /?page=$1amp;cat=$2amp;subcat=$3 [NC,QSA,L]
RewriteRule ^handler1/([^/] )/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1amp;cat=$2amp;subcat=$3subsubcat=$4 [NC,QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler2/([^/] )/?$ /?othervar1=$1 [NC,QSA,L]
RewriteRule ^handler2/([^/] )/([^/] )/?$ /?othervar1=$1amp;othervar2=$2 [NC,QSA,L]
RewriteRule ^handler2/([^/] )/([^/]*)/([^/]*)/?$ /?othervar1=$1amp;othervar2=$2amp;othervar3=$3 [NC,QSA,L]
RewriteRule ^handler2/([^/] )/([^/]*)/([^/]*)/([^/]*)/?$ /?othervar1=$1amp;othervar2=$2amp;othervar3=$3othervar4=$4 [NC,QSA,L]
.htaccess файл для опции 1
Options FollowSymlinks -MultiViews
RewriteEngine on
# 404 handler
ErrorDocument 404 /notFound.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/] )/([^/] )(/.*)?$ $3?$1=$2 [N,QSA,DPI]
RewriteRule ^(/[^/] |[^/] /|/?)$ /index.php [L,QSA,DPI]
Используя эти правила, URL http://localhost/n1/v1/n2/v2/n3/v3/n4/v4
будет ВНУТРЕННЕ перенаправлен на http://localhost/?n4=v4amp;n3=v3amp;n2=v2amp;n1=v1
обработку каждой пары сегментов URL, разделенных /
как name-value
пара для QUERY_STRING. НО имейте в виду, если URI не имеет четного числа сегментов, например: http://localhost/n1/v1/n2/
тогда он будет перенаправлен на http://localhost/?n1=v1
, отбрасывая лишний n2.
Комментарии:
1. @anubhava. Спасибо за ваш ответ. Я бы предпочел использовать вариант 2 для моего текущего проекта, но я уверен, что мне и многим другим, читающим в будущем, также потребуется вариант 1. Если бы вы могли предоставить вариант 2 для меня и, если можете, вариант 1 для других зрителей, и я мог бы использовать его сам в другом проекте. Кроме того, я думал, что «Options FollowSymLinks -MultiViews» идет перед «RewriteEngine on». Это всегда выполняется после или только для этой версии? Спасибо за всю вашу помощь.
2.
Options FollowSymlinks -MultiViews
я полагаю, может идти до или послеRewriteEngine on
. Хорошо, я предоставлю вам. правила htaccess для обоих вариантов за короткое время.3. @anubhava. Пожалуйста, убедитесь, что в случае возникновения ошибки, такой как 404, он все еще может перейти на указанную страницу, например, ErrorDocument 404 /404.php. Спасибо вам еще раз.
4. Извините, был занят срочной работой. Я предоставил .htaccess для варианта 2 выше. Пожалуйста, попробуйте это и дайте мне знать. Я также предоставлю вам. правило htaccess для варианта 1 сегодня вечером.
5. @anubhava. Я совсем новичок на этом сайте. Где вы разместите новые коды .htaccess? Вы просто измените ответ выше или он будет отправлен куда-нибудь еще? Спасибо.