Ответ 1
Вот несколько трюков для создания стека RewriteCond
применимы к нескольким RewriteRule
, отсортированным по возрастанию WTF в минуту. Но это конфигурация, а не код, поэтому эти правила не применяются, не так ли?: -)
1. Переменная среды
Когда у вас много RewriteCond
, сохранение их результата в переменной среды, а затем тестирование в каждом правиле более компактно.
# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# Store environment variable.
RewriteRule ^ - [E=TRUE:YEP]
# Assert environment variable in remaining RewriteRule's.
RewriteCond %{ENV:TRUE} =YEP
RewriteRule Rule1
RewriteCond %{ENV:TRUE} =YEP
RewriteRule Rule2
RewriteCond %{ENV:TRUE} =YEP
RewriteRule Rule3
2. Пропустить флаг
Этот немного тонкий. Используя флаг [S]
или [skip]
, вы можете пропустить весь блок RewriteRule
.
# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# If RewriteCond match, skip the next RewriteRule.
RewriteRule ^ - [skip=1]
# Otherwise, this rule will match and the rest will be skipped.
RewriteRule ^ - [skip=3]
RewriteRule Rule1
RewriteRule Rule2
RewriteRule Rule3
Это действует как оператор if с условием RewriteCond
, а RewriteRule
является блоком кода.
Вы получаете меньше дублирования, но компромисс - это код менее понятный, и вам нужно обновлять [skip=N]
каждый раз, когда вы добавляете или удаляете правило из этого набора N RewriteRule
с.
< удовольствие >
Хорошо, если вы все еще читаете, здесь вы найдете еще два решения, в которых WTF в минуту достигают и превышают критический точка. Они предназначены только для развлечения, и вы поймете, почему.
3. Пропустить флаг без N
Да, есть способ использовать флаг [skip]
без включения N, число RewriteRule
, к которому вы хотите применить стек RewriteCond
. То есть... если вы включаете пару RewriteCond
перед каждым RewriteRule
, и о да, еще один в конце.
# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# If RewriteCond match, skip the next RewriteRule.
RewriteRule ^ - [skip=1] # succeeded
RewriteRule ^ - [skip=2] # failed
RewriteRule Rule1
RewriteRule ^ - [skip=1] # succeeded
RewriteRule ^ - [skip=2] # failed
RewriteRule Rule2
RewriteRule ^ - [skip=1] # succeeded
RewriteRule ^ - [skip=2] # failed
RewriteRule Rule3
RewriteRule ^ - # no-op to cover for last [skip=2] rule
Трюк заключается в том, что каждое правило [skip=1]
обрабатывается тогда и только тогда, когда предел RewriteCond
преуспел, и каждое правило [skip=2]
обрабатывается тогда и только тогда, когда оно не выполнено.
4. Маркер URL
Используйте часть URL для сохранения состояния, а затем сопоставьте его с вашим RewriteRule
.
# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# If RewriteCond match, prepend bogus marker "M#" to internal URL.
RewriteRule .* M#$0
# All your RewriteRule test for this marker plus whatever else.
RewriteRule ^M#.*Rule1
RewriteRule ^M#.*Rule2
RewriteRule ^M#.*Rule3
# Finally, don't forget to strip off the bogus marker.
RewriteRule ^M#(.*) $1
Новый URL-адрес с маркером недействителен, но последний RewriteRule
возвращает его, правильно? Ну, только если он будет обработан, поэтому не позволяйте URL-адресу маркера избежать этого раунда обработки mod_rewrite, прежде чем он будет отменен. Тогда вы получите 404.