Mod переписать правило конфликт сводит меня с ума


У меня есть .htaccess следующим образом, и некоторые правила конфликтуют - мне нужно как-то сделать условие, чтобы они не

RewriteEngine On
RewriteRule ^search$ results_template.php [L]
RewriteRule ^load-([a-z0-9-]+)$ index.php?key=$1 [L]
RewriteRule ^([a-z0-9-]+)$ http://domain.com/share/index.php?key=$1 [L]

The .файл htaccess находится по адресу http://domain.com/directory/.htaccess


Первое правило должно просто переписать имя search на results_template.php и прекратить обработку других правил

http://domain.com/directory/search

Нагрузки

http://domain.com/directory/results_template.php


Предполагается, что второе правило берет abcdef-1 из

http://domain.com/directory/load-abcdef-1

И отправить его в качестве параметра в

http://domain.com/directory/index.php?key=abcdef-1 а затем прекратить обработку правил.


Предполагается, что третье правило берет abcdef-1 из

http://domain.com/directory/abcdef-1

И отправить его в качестве параметра в

http://domain.com/share/index.php?key=abcdef-1 а затем прекратить обработку правил.


Проблема, с которой я сталкиваюсь, не имеет значения, как я пытаюсь заставить их хорошо играть вместе, когда я прошу http://domain.com/directory/search вызывается третье правило, и я переориентированный.

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

3 ответа:

Вам понадобятся секунды перезаписи:

RewriteEngine On
RewriteBase /directory
RewriteRule ^search$ results_template.php [L]
RewriteRule ^load-([a-z0-9-]+)$ index.php?key=$1 [L] 
RewriteCond %{QUERY_STRING} !^results_template.php
RewriteRule ^([a-z0-9-]+)$ http://domain.com/share/index.php?key=$1 [L]

Например, пользователь запрашивает / ищет, затем запрос преобразуется в results_template.РНР. С этим новым запросом / results_template.php все правила проверяются еще раз, и, конечно, последнее правило подходит, так как оно является наиболее общим.

Вам нужно добавить флаг [NS] к третьему правилу. Это делает его не срабатывающим на внутренних суб-запросах.

Ваша проблема заключается в том, что @Jan объяснил, что когда первый идентификатор перезаписи сделан search становится results_template.php. Чтобы понять это полностью, я добавлю, что тег [L] на перезаписи действительно останавливает перезапись и толкает результирующий путь к Apache, но на самом деле внутреннее перенаправление выполняется в apache и mod-rewrite повторно применяется после этого внутреннего перенаправления.

Это самое сложное, что можно понять с mod-rewrite. Использование RewriteLog и RewriteLogLevel может значительно помочь вам обнаружить такие проблемы при работе с тезисами не так-то просто по правилам.

Нет, решение, предложенное Яном, будет работать, но существует более общее решение. Если вы хотите, чтобы ваши правила применялись только один раз, только на url, предоставленном браузерами, и если вы не связываете несколько уровней перенаправления, то самый простой способ обеспечить ваши правила - это Не допускайте их применения после внутреннего перенаправления . И это можно сделать, проверяя перед каждым правилом, что окружающая среда, ent переменная REDIRECT_STATUS пуста

# prevent this rule from being applied after first pass
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ...

EDIT

Но я только что читал ответ @baynezy (+1), и тег [NS] или [nosubreq], похоже, делает то же самое. Тебе тоже стоит попробовать.