RewriteRule тонкие различия - одно и то же? - PullRequest
1 голос
/ 14 декабря 2011

Я пытаюсь лучше понять mod_rewrite, и я столкнулся с некоторыми различиями, которые я думаю делают то же самое? В этом случае нет существующих файлов или каталогов и перезаписывается на страницу index.php.

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]

Нужно ли мне [ИЛИ] или я могу его отключить?

Каковы различия или преимущества следующих правил? В настоящее время я использую первый, но я встречал последние четыре в таких местах, как WordPress:

#currently using
RewriteRule ^(.+)$ index\.php?$1 [L]

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

1 Ответ

0 голосов
/ 14 декабря 2011

Нужно ли мне [ИЛИ] или я могу его отключить?

В этом случае вам нужен [OR], потому что RewriteCond по своей природе ANDed , и дело не в том, что запрос является как файлом, так и каталогом (что касается mod_rewrite).

RewriteRule ^(.+)$ index\.php?$1 [L]

Это переписывает все запросы, которые не для корня документа (например, http://domain.com/) в качестве строки запроса для index.php, таким образом, запрос для http://domain.com/some/path/file.html получается внутренне переписан на index.php?some/path/file.html

RewriteRule ^index\.php$ - [L]

Это правило, предотвращающее перезапись цикла. Механизм перезаписи будет продолжать цикл по всем правилам, пока URI не будет одинаковым до итерации перезаписи и после (без строки запроса). Если URI начинается с index.php, просто остановите текущую итерацию перезаписи (что делает - ). Механизм перезаписи видит, что URI перед отправкой через правила был index.php , а после правил был index.php , таким образом механизм перезаписи останавливается, и вся перезапись выполняется. Это препятствует тому, чтобы mod_rewrite переписывал вещи в index.php?index.php, что первое правило сделало бы при втором проходе через механизм перезаписи, если бы не это правило.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Это ловушка. Если первое правило никогда не применяется, и запрос не существует для существующего файла или каталога, отправьте запрос в index.php. Хотя в этом случае похоже, что это правило никогда не будет применено.


EDIT:

есть ли способ игнорировать определенное правило, если условие истинно? Например, www.domain.com/some/path> index.php? Some / path, но если URI www.domain.com/this/path> не перезаписывать?

Вы должны добавить 2 условия, одно из которых проверяет, чтобы запрошенный хост не был"www.domain.com", и одно, чтобы проверить, что URI не является"/ this / path":

RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$  [NC,OR]
RewriteCond %{REQUEST_URI} !^/some/path 

[NC] указывает, что соответствие условия должно игнорировать регистр, поэтому, когда кто-то вводит URL http://WWW.domain.com/ в свою адресную строку, он будет совпадать (или в этом случае не совпадать). Второе условие соответствует, когда URI начинается с"/ some / path", что означает, что запросы на http://domain.com/some/path/file.html будут совпадать и НЕ будут перезаписаны. Если вы хотите точно соответствовать «/ some / path», то регулярное выражение должно быть !^/some/path$.

Почему бы не использовать [ИЛИ] в последнем блоке между! -F и! -D?

Это логическое отрицание -f ИЛИ -d : «если файл существует, не переписывать, ИЛИ, если каталог существует, не переписывать« превращается в », если файл не не существует, И если каталог не не существует, то переписать "

...