MOD_REWRITE для переменных URL, удаление пустых параметров и использование более 1 поля для первой и второй переменных

#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? Вы просто измените ответ выше или он будет отправлен куда-нибудь еще? Спасибо.