MOD_REWRITE для переменных URL, удаление пустых параметров и использование более 1 поля для первой и второй переменных - PullRequest
4 голосов
/ 25 апреля 2011

У меня есть предыдущий вопрос, на который был получен очень хороший ответ, но мне нужна поправка, и я не смог ответить, поэтому создал новый вопрос.

Мне потребовался mod_rewrite, который сделал следующее:

www.example.com?page=var1&cat=var2&subcat=var3&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=$1&cat=$2 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3&subsubcat=$4 [L]

Это работает, но мне нужно, чтобы у меня была возможность определить, какое поле используется для какой переменной, и определить разницу.

Например, если у нас обычно есть следующие две строки, легко определить, какое поле подходит для какой переменной:

www.example.com?page=var1&cat=var2&subcat=var3&subsubcat=var4

www.example.com?othervar1=var1&othervar2=var2&othervar3=var3&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 Ответ

2 голосов
/ 25 апреля 2011

OK сначала опции 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: В вашем URL-адресе должны быть var name и var value, например:

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=$1&cat=$2 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3subsubcat=$4 [NC,QSA,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler2/([^/]+)/?$ /?othervar1=$1 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]+)/?$ /?othervar1=$1&othervar2=$2 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]*)/([^/]*)/?$ /?othervar1=$1&othervar2=$2&othervar3=$3 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?othervar1=$1&othervar2=$2&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=v4&n3=v3&n2=v2&n1=v1, обрабатывая каждую пару сегментов URL-адресов, разделенных /, как пару name-value для QUERY_STRING. НО имейте в виду, если URI не имеет четного числа сегментов, например: http://localhost/n1/v1/n2/, то он будет перенаправлен на http://localhost/?n1=v1, отбрасывая дополнительные n2.

...