Несколько RewriteRules для одного RewriteCond в.htaccess

У меня есть следующая команда в моем.htaccess

    RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
    RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
    RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

%2 не работает во второй и последующих строках. Могу ли я определить любую переменную для%2 и использовать ее во всех командах RewriteRule? Следующая команда работает

     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

Но я хочу использовать%2 для нескольких строк правила без дублирования условия.

4 ответа

Решение

Переменная должна быть сохранена как Apache var, тогда ее можно использовать без повторяющихся условий.

Сохранение в Apache переменных показано во второй строке. Использование сохраненных переменных в 3-й и 4-й строках.

RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
RewriteRule .? - [E=Wa:%1,E=Wb:%2]
RewriteRule ^(.*?)-([a-z]+) %{ENV:Wb}/$1.%{ENV:Wb} [L]
RewriteRule ^(.*?)-([0-9]+)([a-z]) %{ENV:Wb}/$1$3.$2 [L]

Вы можете использовать флаг RewriteRule S|skip связать кратные RewriteRules с одним RewriteCond (или с набором RewriteConds). Вот пример, который применяет один Cond к трем Правилам:

RewriteCond  %{HTTP_HOST}  !^www.mydomain.com$
# skip rules if NOT within domain - only way to tie multiple rules to one cond
RewriteRule  .?  -  [S=3]
RewriteRule  ^path1(/.*)$  /otherpath1$1
RewriteRule  ^path2(/.*)$  /otherpath2$1
RewriteRule  ^path3(/.*)$  /otherpath3$1

Чтобы изменить существующий Cond для работы с несколькими Правилами, вы должны:

  • Отрицайте условие (добавьте его!)
  • Если у вас есть несколько RewriteConds:
    Измените логические AND в Conds на OR и наоборот.
  • Добавьте правило пропуска перезаписи перед всеми правилами, которые вы хотите связать с условием (ями). Установите для параметра S количество пропущенных строк правила.

Помните, что невозможно использовать какие-либо обратные ссылки, указывающие на RewriteCond (например,%1) в пропущенных правилах. Они доступны только в пропускающем RewriteRule.

Понятно, что это не очень весело, особенно когда все растет и усложняется. Однако есть менее известная опция оператора RewriteRule, которая сообщает apache пропустить следующее число N оператора RewriteRule. [S=N]. Поэтому вместо того, чтобы каждый раз проверять, является ли запрос НЕ файлом И НЕ является ли каталогом, мы могли бы сделать это: Блок кода

#
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [S=3]
RewriteRule ^([^./]+)/$ http://www.santweb.co.uk/$1 [L]
RewriteRule ^([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2 [L]
RewriteRule ^([^./]+)/([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2/$3 [L]

#

Я нашел это по адресу: http://www.sant-media.co.uk/2010/03/applying-rewritecond-to-multiple-rewriterule-in-htaccess/

Я думаю, что это полезно

Из Apache 2.4 вы можете использовать <If> директива:

RewriteEngine On
<If "%{HTTP:Upgrade} == 'websocket'">
    RewriteRule /nidoran/(.*)           ws://localhost:8080/nidoran/$1 [P,L]
    RewriteRule /kakuna/(.*)           ws://localhost:8081/kakuna/$1 [P,L]
    RewriteRule /porygon/(.*)           ws://localhost:8082/porygon/$1 [P,L]
</If>

http://httpd.apache.org/docs/2.4/expr.html

Как правило, вы не можете использовать несколько операторов RewriteRule после одного RewriteCond. Но вы можете сделать небольшой трюк с вашими условиями, если хотите, как показано на:

https://serverfault.com/questions/162586/one-rewritecond-for-multiple-rewriterules
или же
http://www.sant-media.co.uk/2010/03/applying-rewritecond-to-multiple-rewriterule-in-htaccess/

Другие вопросы по тегам